
//-------------------------------------------------------------------------
//   Copyright 2002-2023 National Technology & Engineering Solutions of
//   Sandia, LLC (NTESS).  Under the terms of Contract DE-NA0003525 with
//   NTESS, the U.S. Government retains certain rights in this software.
//
//   This file is part of the Xyce(TM) Parallel Electrical Simulator.
//
//   Xyce(TM) is free software: you can redistribute it and/or modify
//   it under the terms of the GNU General Public License as published by
//   the Free Software Foundation, either version 3 of the License, or
//   (at your option) any later version.
//
//   Xyce(TM) is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU General Public License for more details.
//
//   You should have received a copy of the GNU General Public License
//   along with Xyce(TM).
//   If not, see <http://www.gnu.org/licenses/>.
//-------------------------------------------------------------------------


//-------------------------------------------------------------------------
//
// Purpose        :
//
// Special Notes  : Generated from verilog file mvs_2_0_0_etsoi.va with ADMS
//                  interface for Xyce 7.7.0
//                  DO NOT EDIT THIS FILE DIRECTLY!  It may be overwritten!
//
// Creator        : admsXml-2.3.7
//
// Creation Date  : Mon, 09 Jan 2023 12:53:26
//
//-------------------------------------------------------------------------
// Shut up clang's warnings about extraneous parentheses
#ifdef __clang__
#  pragma clang diagnostic ignored "-Wparentheses-equality"
#endif

#include <Xyce_config.h>
#include <N_DEV_ADMSmvs_2_0_0_etsoi.h>


#include <N_DEV_Const.h>
#include <N_DEV_DeviceOptions.h>
#include <N_DEV_DeviceMaster.h>
#include <N_DEV_ExternData.h>
#include <N_DEV_SolverState.h>
#include <N_DEV_Message.h>

#include <N_LAS_Matrix.h>
#include <N_LAS_Vector.h>


#include <N_UTL_FeatureTest.h>
#include <unordered_map>
using std::unordered_map;

#include <algorithm>

// Xyce_config.h contains a VERSION macro from autoconf, and some
// Verilog-A models like to define a variable of that name.  This can be
// a serious problem, and we don't need the VERSION macro.  Get rid of it.
// This must happen *after* all includes of Xyce headers, each of which
// includes Xyce_config.h!
#ifdef VERSION
#undef VERSION
#endif

namespace Xyce {
namespace Device {
namespace ADMSmvs_2_0_0_etsoi {
JacobianStamp Instance::jacStamp;
IdVector Instance::nodeMap;
PairMap Instance::pairToJacStampMap;


//This is necessary because the IntPair usage can trip undefined references
    const int Instance::admsNodeID_d;
    const int Instance::admsNodeID_g;
    const int Instance::admsNodeID_s;
    const int Instance::admsNodeID_di;
    const int Instance::admsNodeID_si;
    const int Instance::admsNodeID_sf;
     const int Instance::admsNodeID_GND;
   // Additional IDs for branch equations
    const int Instance::admsBRA_ID_sf_GND;


void
Traits::loadInstanceParameters(ParametricData<ADMSmvs_2_0_0_etsoi::Instance> &p)
{
  // Set up each parameter directly, using the up-cased variable name
  // as the tag.

  // This kludge is to force us always to have an instance parameter
  // that the device manager can set to the temperature, even if we have
  // no "TEMP".
  p.addPar("XYCEADMSINSTTEMP", 0.0, &ADMSmvs_2_0_0_etsoi::Instance::admsInstTemp)
    .setExpressionAccess(NO_DOC)
    .setUnit(U_DEGK)
    .setCategory(CAT_TEMP)
    .setDescription("Internal-use parameter for setting device instance temperature");


}

void Traits::loadModelParameters(ParametricData<ADMSmvs_2_0_0_etsoi::Model> &p)
{
  // Set up each parameter directly, using the up-cased variable name
  // as the tag.

  // This kludge is to force us always to have a model parameter
  // that the device manager can set to the temperature, even if we have
  // no "TEMP".
  p.addPar("XYCEADMSMODTEMP", 0.0, &ADMSmvs_2_0_0_etsoi::Model::admsModTemp)
    .setExpressionAccess(NO_DOC)
    .setUnit(U_DEGK)
    .setCategory(CAT_TEMP)
    .setDescription("Internal-use parameter for setting device model temperature");
  p.addPar("VERSION", static_cast<double>(2.00), &ADMSmvs_2_0_0_etsoi::Model::version)
#ifdef Xyce_ADMS_SENSITIVITIES
    .setAnalyticSensitivityAvailable(true)
    .setSensitivityFunctor(&modSens)
#endif // Xyce_ADMS_SENSITIVITIES
;
  p.addPar("TYPE", static_cast<int>(1), &ADMSmvs_2_0_0_etsoi::Model::type);
  p.addPar("W", static_cast<double>(1.0e-6), &ADMSmvs_2_0_0_etsoi::Model::W)
#ifdef Xyce_ADMS_SENSITIVITIES
    .setAnalyticSensitivityAvailable(true)
    .setSensitivityFunctor(&modSens)
#endif // Xyce_ADMS_SENSITIVITIES
;
  p.addPar("LGDR", static_cast<double>(80.0e-9), &ADMSmvs_2_0_0_etsoi::Model::Lgdr)
#ifdef Xyce_ADMS_SENSITIVITIES
    .setAnalyticSensitivityAvailable(true)
    .setSensitivityFunctor(&modSens)
#endif // Xyce_ADMS_SENSITIVITIES
;
  p.addPar("DLG", static_cast<double>(10.5e-9), &ADMSmvs_2_0_0_etsoi::Model::dLg)
#ifdef Xyce_ADMS_SENSITIVITIES
    .setAnalyticSensitivityAvailable(true)
    .setSensitivityFunctor(&modSens)
#endif // Xyce_ADMS_SENSITIVITIES
;
  p.addPar("CINS", static_cast<double>(3.17e-2), &ADMSmvs_2_0_0_etsoi::Model::Cins)
#ifdef Xyce_ADMS_SENSITIVITIES
    .setAnalyticSensitivityAvailable(true)
    .setSensitivityFunctor(&modSens)
#endif // Xyce_ADMS_SENSITIVITIES
;
  p.addPar("TJUN", static_cast<double>(300.0), &ADMSmvs_2_0_0_etsoi::Model::Tjun)
#ifdef Xyce_ADMS_SENSITIVITIES
    .setAnalyticSensitivityAvailable(true)
    .setSensitivityFunctor(&modSens)
#endif // Xyce_ADMS_SENSITIVITIES
;
  p.addPar("ENERGY_DIFF_VOLT", static_cast<double>(0.153), &ADMSmvs_2_0_0_etsoi::Model::energy_diff_volt)
#ifdef Xyce_ADMS_SENSITIVITIES
    .setAnalyticSensitivityAvailable(true)
    .setSensitivityFunctor(&modSens)
#endif // Xyce_ADMS_SENSITIVITIES
;
  p.addPar("DELTA", static_cast<double>(0.120), &ADMSmvs_2_0_0_etsoi::Model::delta)
#ifdef Xyce_ADMS_SENSITIVITIES
    .setAnalyticSensitivityAvailable(true)
    .setSensitivityFunctor(&modSens)
#endif // Xyce_ADMS_SENSITIVITIES
;
  p.addPar("N0", static_cast<double>(1.35), &ADMSmvs_2_0_0_etsoi::Model::n0)
#ifdef Xyce_ADMS_SENSITIVITIES
    .setAnalyticSensitivityAvailable(true)
    .setSensitivityFunctor(&modSens)
#endif // Xyce_ADMS_SENSITIVITIES
;
  p.addPar("RS0", static_cast<double>(160.0e-6), &ADMSmvs_2_0_0_etsoi::Model::Rs0)
#ifdef Xyce_ADMS_SENSITIVITIES
    .setAnalyticSensitivityAvailable(true)
    .setSensitivityFunctor(&modSens)
#endif // Xyce_ADMS_SENSITIVITIES
;
  p.addPar("MT", static_cast<double>(0.19), &ADMSmvs_2_0_0_etsoi::Model::mt)
#ifdef Xyce_ADMS_SENSITIVITIES
    .setAnalyticSensitivityAvailable(true)
    .setSensitivityFunctor(&modSens)
#endif // Xyce_ADMS_SENSITIVITIES
;
  p.addPar("ML", static_cast<double>(0.89), &ADMSmvs_2_0_0_etsoi::Model::ml)
#ifdef Xyce_ADMS_SENSITIVITIES
    .setAnalyticSensitivityAvailable(true)
    .setSensitivityFunctor(&modSens)
#endif // Xyce_ADMS_SENSITIVITIES
;
  p.addPar("NU", static_cast<double>(0.7), &ADMSmvs_2_0_0_etsoi::Model::nu)
#ifdef Xyce_ADMS_SENSITIVITIES
    .setAnalyticSensitivityAvailable(true)
    .setSensitivityFunctor(&modSens)
#endif // Xyce_ADMS_SENSITIVITIES
;
  p.addPar("MU_EFF", static_cast<double>(1.0), &ADMSmvs_2_0_0_etsoi::Model::mu_eff)
#ifdef Xyce_ADMS_SENSITIVITIES
    .setAnalyticSensitivityAvailable(true)
    .setSensitivityFunctor(&modSens)
#endif // Xyce_ADMS_SENSITIVITIES
;
  p.addPar("KSEE", static_cast<double>(0.1), &ADMSmvs_2_0_0_etsoi::Model::ksee)
#ifdef Xyce_ADMS_SENSITIVITIES
    .setAnalyticSensitivityAvailable(true)
    .setSensitivityFunctor(&modSens)
#endif // Xyce_ADMS_SENSITIVITIES
;
  p.addPar("B", static_cast<double>(6.8e-9), &ADMSmvs_2_0_0_etsoi::Model::B)
#ifdef Xyce_ADMS_SENSITIVITIES
    .setAnalyticSensitivityAvailable(true)
    .setSensitivityFunctor(&modSens)
#endif // Xyce_ADMS_SENSITIVITIES
;
  p.addPar("DQM0", static_cast<double>(4.6e-9), &ADMSmvs_2_0_0_etsoi::Model::dqm0)
#ifdef Xyce_ADMS_SENSITIVITIES
    .setAnalyticSensitivityAvailable(true)
    .setSensitivityFunctor(&modSens)
#endif // Xyce_ADMS_SENSITIVITIES
;
  p.addPar("EPS", static_cast<double>(13.6), &ADMSmvs_2_0_0_etsoi::Model::eps)
#ifdef Xyce_ADMS_SENSITIVITIES
    .setAnalyticSensitivityAvailable(true)
    .setSensitivityFunctor(&modSens)
#endif // Xyce_ADMS_SENSITIVITIES
;
  p.addPar("THETA", static_cast<double>(2.5), &ADMSmvs_2_0_0_etsoi::Model::theta)
#ifdef Xyce_ADMS_SENSITIVITIES
    .setAnalyticSensitivityAvailable(true)
    .setSensitivityFunctor(&modSens)
#endif // Xyce_ADMS_SENSITIVITIES
;
  p.addPar("BETA", static_cast<double>(1.55), &ADMSmvs_2_0_0_etsoi::Model::beta)
#ifdef Xyce_ADMS_SENSITIVITIES
    .setAnalyticSensitivityAvailable(true)
    .setSensitivityFunctor(&modSens)
#endif // Xyce_ADMS_SENSITIVITIES
;
  p.addPar("ND", static_cast<double>(0.0), &ADMSmvs_2_0_0_etsoi::Model::nd)
#ifdef Xyce_ADMS_SENSITIVITIES
    .setAnalyticSensitivityAvailable(true)
    .setSensitivityFunctor(&modSens)
#endif // Xyce_ADMS_SENSITIVITIES
;

}

//-----------------------------------------------------------------------------
// Function      : Instance::processParams
// Purpose       :
// Special Notes :
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
bool Instance::processParams()
{
  // set any non-constant parameter defaults

  // copy any model variables that have associated instance variables, but
  // are only given in the model card:



  // Set any parameters that were not given and whose defaults depend on other
  // parameters:


// Now we need to check that any parameters are within their ranges as
  // specified in the verilog:


  // this seems a little stupid, but verilog models that use $temperature
  // don't also use a defined parameter "Temp", and count on $temperature
  // to be the one the simulator wants:

  updateTemperature(admsInstTemp);

  // and of course, this routine is where we should put the initial_instance
  // stuff


  return true;
}

//-----------------------------------------------------------------------------
// Function      : Instance::Instance
// Purpose       : "instance block" constructor
// Special Notes :
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------

Instance::Instance(
  const Configuration & configuration,
  const InstanceBlock & instance_block,
  Model &               model,
  const FactoryBlock &  factory_block)
  : DeviceInstance(instance_block, configuration.getInstanceParameters(), factory_block),
    model_(model),
    li_d(-1),
    li_g(-1),
    li_s(-1),
    li_di(-1),
    li_si(-1),
    li_sf(-1),
    li_BRA_sf_GND(-1),
    li_branch_id(-1),
    li_branch_ig(-1),
    li_branch_is(-1),
    f_di_Equ_si_Node_Ptr(0),
    f_si_Equ_si_Node_Ptr(0),
    f_di_Equ_di_Node_Ptr(0),
    f_si_Equ_di_Node_Ptr(0),
    f_di_Equ_sf_Node_Ptr(0),
    f_si_Equ_sf_Node_Ptr(0),
    f_d_Equ_di_Node_Ptr(0),
    f_d_Equ_d_Node_Ptr(0),
    f_di_Equ_d_Node_Ptr(0),
    f_si_Equ_s_Node_Ptr(0),
    f_s_Equ_s_Node_Ptr(0),
    f_s_Equ_si_Node_Ptr(0),
    f_sf_Equ_BRA_sf_GND_Var_Ptr(0),
    f_BRA_sf_GND_Equ_sf_Node_Ptr(0),
    f_BRA_sf_GND_Equ_si_Node_Ptr(0),
    f_BRA_sf_GND_Equ_g_Node_Ptr(0),
    f_BRA_sf_GND_Equ_di_Node_Ptr(0),
    q_di_Equ_si_Node_Ptr(0),
    q_si_Equ_si_Node_Ptr(0),
    q_di_Equ_di_Node_Ptr(0),
    q_si_Equ_di_Node_Ptr(0),
    q_di_Equ_sf_Node_Ptr(0),
    q_si_Equ_sf_Node_Ptr(0),
    q_d_Equ_di_Node_Ptr(0),
    q_d_Equ_d_Node_Ptr(0),
    q_di_Equ_d_Node_Ptr(0),
    q_si_Equ_s_Node_Ptr(0),
    q_s_Equ_s_Node_Ptr(0),
    q_s_Equ_si_Node_Ptr(0),
    q_sf_Equ_BRA_sf_GND_Var_Ptr(0),
    q_BRA_sf_GND_Equ_sf_Node_Ptr(0),
    q_BRA_sf_GND_Equ_si_Node_Ptr(0),
    q_BRA_sf_GND_Equ_g_Node_Ptr(0),
    q_BRA_sf_GND_Equ_di_Node_Ptr(0),
    A_di_Equ_si_NodeOffset(-1),
    A_si_Equ_si_NodeOffset(-1),
    A_di_Equ_di_NodeOffset(-1),
    A_si_Equ_di_NodeOffset(-1),
    A_di_Equ_sf_NodeOffset(-1),
    A_si_Equ_sf_NodeOffset(-1),
    A_d_Equ_di_NodeOffset(-1),
    A_d_Equ_d_NodeOffset(-1),
    A_di_Equ_d_NodeOffset(-1),
    A_si_Equ_s_NodeOffset(-1),
    A_s_Equ_s_NodeOffset(-1),
    A_s_Equ_si_NodeOffset(-1),
    A_sf_Equ_BRA_sf_GND_Var_Offset(-1),
    A_BRA_sf_GND_Equ_sf_Node_Offset(-1),
    A_BRA_sf_GND_Equ_si_Node_Offset(-1),
    A_BRA_sf_GND_Equ_g_Node_Offset(-1),
    A_BRA_sf_GND_Equ_di_Node_Offset(-1),
    admsTemperature(getDeviceOptions().temp.getImmutableValue<double>())

{
    numIntVars = 3 + 1;
    numExtVars = 3;

  // Right now, we only have store for limited probes and output vars...
  setNumStoreVars(0+0);

  // Do not allocate "branch" (lead current) vectors by default
  setNumBranchDataVars(0);
  numBranchDataVarsIfAllocated = 3;

  leadCurrentF.resize(3);
  leadCurrentQ.resize(3);

  // Set up jacobian stamp:
  // Create a vector of the non-zero elements of the stamp
PairVector jacobianElements;
    jacobianElements.push_back(IntPair(admsNodeID_d,admsNodeID_di));
    jacobianElements.push_back(IntPair(admsNodeID_d,admsNodeID_d));
    jacobianElements.push_back(IntPair(admsNodeID_s,admsNodeID_s));
    jacobianElements.push_back(IntPair(admsNodeID_s,admsNodeID_si));
    jacobianElements.push_back(IntPair(admsNodeID_di,admsNodeID_si));
    jacobianElements.push_back(IntPair(admsNodeID_di,admsNodeID_di));
    jacobianElements.push_back(IntPair(admsNodeID_di,admsNodeID_sf));
    jacobianElements.push_back(IntPair(admsNodeID_di,admsNodeID_d));
    jacobianElements.push_back(IntPair(admsNodeID_si,admsNodeID_si));
    jacobianElements.push_back(IntPair(admsNodeID_si,admsNodeID_di));
    jacobianElements.push_back(IntPair(admsNodeID_si,admsNodeID_sf));
    jacobianElements.push_back(IntPair(admsNodeID_si,admsNodeID_s));
    // Extra columns for dependence on branches
    jacobianElements.push_back(IntPair(admsNodeID_sf,admsBRA_ID_sf_GND));
    // Jacobian rows for branch equations
jacobianElements.push_back(IntPair(admsBRA_ID_sf_GND,admsNodeID_sf));   // Branch eqn sf,GND - node sf
jacobianElements.push_back(IntPair(admsBRA_ID_sf_GND,admsNodeID_si));   // Branch eqn sf,GND - node si
jacobianElements.push_back(IntPair(admsBRA_ID_sf_GND,admsNodeID_g));   // Branch eqn sf,GND - node g
jacobianElements.push_back(IntPair(admsBRA_ID_sf_GND,admsNodeID_di));   // Branch eqn sf,GND - node di



  setDefaultParams();
  setParams(instance_block.params);

  // Real bogosity here...
  if (!given("XYCEADMSINSTTEMP"))
    admsInstTemp=getDeviceOptions().temp.getImmutableValue<double>();

  //calculate any parameters specified as expressions
  updateDependentParameters();

  // calculate dependent (i.e. computed params) and check for errors.
  processParams();

  PairVector collapsedNodes;

// Now generate the jacstamp from what we already have.
// This jacstamp will have all the correct node mapping.  map will be the nodal mapping of original
// node IDs to row/column ids in the reduced (non-sparse) representation of the jacobian.
// (for devices that have no collapsibles, this will be static, so check that it hasn't already
// been filled in)
if (jacStamp.empty())
{
int originalSize = 6+1;
computeJacStampAndMaps(jacobianElements,collapsedNodes,jacStamp,nodeMap,pairToJacStampMap,originalSize);
}

}

//-----------------------------------------------------------------------------
// Function      : Instance::~Instance
// Purpose       : destructor
// Special Notes :
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
Instance::~Instance()
{
}

//-----------------------------------------------------------------------------
// Function      : Instance::registerLIDs
// Purpose       : function for registering, and setting up, local IDs.
// Special Notes :
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
void Instance::registerLIDs( const LocalIdVector & intLIDVecRef,
                             const LocalIdVector & extLIDVecRef)
{
  AssertLIDs(intLIDVecRef.size() == numIntVars);
  AssertLIDs(extLIDVecRef.size() == numExtVars);

  LocalIdVector localLIDVec;

  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
  {
    Xyce::dout() << std::endl << section_divider << std::endl
                 << "In ADMSmvs_2_0_0_etsoi::Instance::register LIDs\n\n"
                 << "name             = " << getName() << std::endl
                 << "number of internal variables: " << numIntVars << std::endl
                 << "number of external variables: " << numExtVars << std::endl;
  }

  // copy over the global ID lists into a local array.
  // The end result of this is an array of LIDs corresponding to all the
  // nodes we actually have, in the order that topology thinks of them
  intLIDVec = intLIDVecRef;
  extLIDVec = extLIDVecRef;
  localLIDVec.resize(numExtVars+numIntVars);
  for (int localNodeIndex=0;localNodeIndex<numExtVars;++localNodeIndex)
  {
    localLIDVec[localNodeIndex]=extLIDVec[localNodeIndex];
  }
  for (int localNodeIndex=numExtVars;localNodeIndex<numExtVars+numIntVars;++localNodeIndex)
  {
    localLIDVec[localNodeIndex]=intLIDVec[localNodeIndex-numExtVars];
    }

  // Now pull the LIDs for each of our nodes out of the local array.
  // Use the node mapping created by createJacStampAndMaps to handle
  // all the node collapse complications.
  li_d = localLIDVec[nodeMap[admsNodeID_d]];
  li_g = localLIDVec[nodeMap[admsNodeID_g]];
  li_s = localLIDVec[nodeMap[admsNodeID_s]];
  li_di = localLIDVec[nodeMap[admsNodeID_di]];
  li_si = localLIDVec[nodeMap[admsNodeID_si]];
  li_sf = localLIDVec[nodeMap[admsNodeID_sf]];
  li_BRA_sf_GND = localLIDVec[nodeMap[admsBRA_ID_sf_GND]];


  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
  {
    Xyce::dout() << "\nSolution and RHS variables:\n";
      Xyce::dout() << "\nli_d = " << li_d << std::endl;
      Xyce::dout() << "\nli_g = " << li_g << std::endl;
      Xyce::dout() << "\nli_s = " << li_s << std::endl;
      Xyce::dout() << "\nli_di = " << li_di << std::endl;
      Xyce::dout() << "\nli_si = " << li_si << std::endl;
      Xyce::dout() << "\nli_sf = " << li_sf << std::endl;
      Xyce::dout() << "\nli_BRA_sf_GND = " << li_BRA_sf_GND << std::endl;

    Xyce::dout() << "\nEnd of ADMSmvs_2_0_0_etsoi::Instance::register LIDs\n";
    Xyce::dout() << section_divider << std::endl;
  }
}

//-----------------------------------------------------------------------------
// Function      : Instance::loadNodeSymbols
// Purpose       :
// Special Notes :
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
void Instance::loadNodeSymbols(Util::SymbolTable &symbol_table) const
{
    addInternalNode(symbol_table, li_di, getName(), "di");
    addInternalNode(symbol_table, li_si, getName(), "si");
    addInternalNode(symbol_table, li_sf, getName(), "sf");
    addInternalNode(symbol_table, li_BRA_sf_GND, getName(), "sf_GND_branch");

  if (loadLeadCurrent)
  {
    addBranchDataNode( symbol_table, li_branch_id, getName(), "BRANCH_DD");
    addBranchDataNode( symbol_table, li_branch_ig, getName(), "BRANCH_DG");
    addBranchDataNode( symbol_table, li_branch_is, getName(), "BRANCH_DS");


  }
}

//-----------------------------------------------------------------------------
// Function      : Instance::registerStoreLIDs
// Purpose       :
// Special Notes :
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
void Instance::registerStoreLIDs( const LocalIdVector & stoLIDVecRef)
{
  AssertLIDs(stoLIDVecRef.size() == getNumStoreVars());
}

//-----------------------------------------------------------------------------
// Function      : Instance::registerBranchDataLIDs
// Purpose       :
// Special Notes :
// Scope         : public
// Creator       : Eric Keiter, SNL
// Creation Date : 12/09/11
//-----------------------------------------------------------------------------
void Instance::registerBranchDataLIDs(const std::vector<int> & branchLIDVecRef)
{
  AssertLIDs(branchLIDVecRef.size() == getNumBranchDataVars());

  if (loadLeadCurrent)
  {
    int i = 0;
    li_branch_id = branchLIDVecRef[i++];
    li_branch_ig = branchLIDVecRef[i++];
    li_branch_is = branchLIDVecRef[i++];

  }
}

//-----------------------------------------------------------------------------
// Function      : Instance::jacobianStamp
// Purpose       :
// Special Notes :
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
const JacobianStamp & Instance::jacobianStamp() const
{
    return jacStamp;
}

//-----------------------------------------------------------------------------
// Function      : Instance::registerJacLIDs
// Purpose       : Create Offset variables used for referencing jacobian
//                 elements
// Special Notes :
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
void Instance::registerJacLIDs( const JacobianStamp & jacLIDVec)
{
  DeviceInstance::registerJacLIDs(jacLIDVec);  IntPair jacLoc;
    jacLoc = pairToJacStampMap[IntPair(admsNodeID_d,admsNodeID_di)];
    A_d_Equ_di_NodeOffset = jacLIDVec[jacLoc.first][jacLoc.second];
    jacLoc = pairToJacStampMap[IntPair(admsNodeID_d,admsNodeID_d)];
    A_d_Equ_d_NodeOffset = jacLIDVec[jacLoc.first][jacLoc.second];
    jacLoc = pairToJacStampMap[IntPair(admsNodeID_s,admsNodeID_s)];
    A_s_Equ_s_NodeOffset = jacLIDVec[jacLoc.first][jacLoc.second];
    jacLoc = pairToJacStampMap[IntPair(admsNodeID_s,admsNodeID_si)];
    A_s_Equ_si_NodeOffset = jacLIDVec[jacLoc.first][jacLoc.second];
    jacLoc = pairToJacStampMap[IntPair(admsNodeID_di,admsNodeID_si)];
    A_di_Equ_si_NodeOffset = jacLIDVec[jacLoc.first][jacLoc.second];
    jacLoc = pairToJacStampMap[IntPair(admsNodeID_di,admsNodeID_di)];
    A_di_Equ_di_NodeOffset = jacLIDVec[jacLoc.first][jacLoc.second];
    jacLoc = pairToJacStampMap[IntPair(admsNodeID_di,admsNodeID_sf)];
    A_di_Equ_sf_NodeOffset = jacLIDVec[jacLoc.first][jacLoc.second];
    jacLoc = pairToJacStampMap[IntPair(admsNodeID_di,admsNodeID_d)];
    A_di_Equ_d_NodeOffset = jacLIDVec[jacLoc.first][jacLoc.second];
    jacLoc = pairToJacStampMap[IntPair(admsNodeID_si,admsNodeID_si)];
    A_si_Equ_si_NodeOffset = jacLIDVec[jacLoc.first][jacLoc.second];
    jacLoc = pairToJacStampMap[IntPair(admsNodeID_si,admsNodeID_di)];
    A_si_Equ_di_NodeOffset = jacLIDVec[jacLoc.first][jacLoc.second];
    jacLoc = pairToJacStampMap[IntPair(admsNodeID_si,admsNodeID_sf)];
    A_si_Equ_sf_NodeOffset = jacLIDVec[jacLoc.first][jacLoc.second];
    jacLoc = pairToJacStampMap[IntPair(admsNodeID_si,admsNodeID_s)];
    A_si_Equ_s_NodeOffset = jacLIDVec[jacLoc.first][jacLoc.second];
    jacLoc=pairToJacStampMap[IntPair(admsNodeID_sf,admsBRA_ID_sf_GND)];
    A_sf_Equ_BRA_sf_GND_Var_Offset = jacLIDVec[jacLoc.first][jacLoc.second];
    jacLoc = pairToJacStampMap[IntPair(admsBRA_ID_sf_GND,admsNodeID_sf)];
    A_BRA_sf_GND_Equ_sf_Node_Offset = jacLIDVec[jacLoc.first][jacLoc.second];
    jacLoc = pairToJacStampMap[IntPair(admsBRA_ID_sf_GND,admsNodeID_si)];
    A_BRA_sf_GND_Equ_si_Node_Offset = jacLIDVec[jacLoc.first][jacLoc.second];
    jacLoc = pairToJacStampMap[IntPair(admsBRA_ID_sf_GND,admsNodeID_g)];
    A_BRA_sf_GND_Equ_g_Node_Offset = jacLIDVec[jacLoc.first][jacLoc.second];
    jacLoc = pairToJacStampMap[IntPair(admsBRA_ID_sf_GND,admsNodeID_di)];
    A_BRA_sf_GND_Equ_di_Node_Offset = jacLIDVec[jacLoc.first][jacLoc.second];


}

//-----------------------------------------------------------------------------
// Function      : Instance::setupPointers
// Purpose       : Create pointer variables used for referencing jacobian
//                 elements
// Special Notes :
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
void Instance::setupPointers( )
{

  Linear::Matrix & dFdx = *(extData.dFdxMatrixPtr);
  Linear::Matrix & dQdx = *(extData.dQdxMatrixPtr);
    f_d_Equ_di_Node_Ptr = &(dFdx[li_d][A_d_Equ_di_NodeOffset]);
    q_d_Equ_di_Node_Ptr = &(dQdx[li_d][A_d_Equ_di_NodeOffset]);
    f_d_Equ_d_Node_Ptr = &(dFdx[li_d][A_d_Equ_d_NodeOffset]);
    q_d_Equ_d_Node_Ptr = &(dQdx[li_d][A_d_Equ_d_NodeOffset]);
    f_s_Equ_s_Node_Ptr = &(dFdx[li_s][A_s_Equ_s_NodeOffset]);
    q_s_Equ_s_Node_Ptr = &(dQdx[li_s][A_s_Equ_s_NodeOffset]);
    f_s_Equ_si_Node_Ptr = &(dFdx[li_s][A_s_Equ_si_NodeOffset]);
    q_s_Equ_si_Node_Ptr = &(dQdx[li_s][A_s_Equ_si_NodeOffset]);
    f_di_Equ_si_Node_Ptr = &(dFdx[li_di][A_di_Equ_si_NodeOffset]);
    q_di_Equ_si_Node_Ptr = &(dQdx[li_di][A_di_Equ_si_NodeOffset]);
    f_di_Equ_di_Node_Ptr = &(dFdx[li_di][A_di_Equ_di_NodeOffset]);
    q_di_Equ_di_Node_Ptr = &(dQdx[li_di][A_di_Equ_di_NodeOffset]);
    f_di_Equ_sf_Node_Ptr = &(dFdx[li_di][A_di_Equ_sf_NodeOffset]);
    q_di_Equ_sf_Node_Ptr = &(dQdx[li_di][A_di_Equ_sf_NodeOffset]);
    f_di_Equ_d_Node_Ptr = &(dFdx[li_di][A_di_Equ_d_NodeOffset]);
    q_di_Equ_d_Node_Ptr = &(dQdx[li_di][A_di_Equ_d_NodeOffset]);
    f_si_Equ_si_Node_Ptr = &(dFdx[li_si][A_si_Equ_si_NodeOffset]);
    q_si_Equ_si_Node_Ptr = &(dQdx[li_si][A_si_Equ_si_NodeOffset]);
    f_si_Equ_di_Node_Ptr = &(dFdx[li_si][A_si_Equ_di_NodeOffset]);
    q_si_Equ_di_Node_Ptr = &(dQdx[li_si][A_si_Equ_di_NodeOffset]);
    f_si_Equ_sf_Node_Ptr = &(dFdx[li_si][A_si_Equ_sf_NodeOffset]);
    q_si_Equ_sf_Node_Ptr = &(dQdx[li_si][A_si_Equ_sf_NodeOffset]);
    f_si_Equ_s_Node_Ptr = &(dFdx[li_si][A_si_Equ_s_NodeOffset]);
    q_si_Equ_s_Node_Ptr = &(dQdx[li_si][A_si_Equ_s_NodeOffset]);
    f_sf_Equ_BRA_sf_GND_Var_Ptr = &(dFdx[li_sf][A_sf_Equ_BRA_sf_GND_Var_Offset]);
    q_sf_Equ_BRA_sf_GND_Var_Ptr = &(dQdx[li_sf][A_sf_Equ_BRA_sf_GND_Var_Offset]);
    f_BRA_sf_GND_Equ_sf_Node_Ptr = &(dFdx[li_BRA_sf_GND][A_BRA_sf_GND_Equ_sf_Node_Offset]);
    q_BRA_sf_GND_Equ_sf_Node_Ptr =  &(dQdx[li_BRA_sf_GND][A_BRA_sf_GND_Equ_sf_Node_Offset]);
    f_BRA_sf_GND_Equ_si_Node_Ptr = &(dFdx[li_BRA_sf_GND][A_BRA_sf_GND_Equ_si_Node_Offset]);
    q_BRA_sf_GND_Equ_si_Node_Ptr =  &(dQdx[li_BRA_sf_GND][A_BRA_sf_GND_Equ_si_Node_Offset]);
    f_BRA_sf_GND_Equ_g_Node_Ptr = &(dFdx[li_BRA_sf_GND][A_BRA_sf_GND_Equ_g_Node_Offset]);
    q_BRA_sf_GND_Equ_g_Node_Ptr =  &(dQdx[li_BRA_sf_GND][A_BRA_sf_GND_Equ_g_Node_Offset]);
    f_BRA_sf_GND_Equ_di_Node_Ptr = &(dFdx[li_BRA_sf_GND][A_BRA_sf_GND_Equ_di_Node_Offset]);
    q_BRA_sf_GND_Equ_di_Node_Ptr =  &(dQdx[li_BRA_sf_GND][A_BRA_sf_GND_Equ_di_Node_Offset]);


}

// RHS load functions

//-----------------------------------------------------------------------------
// Function      : Instance::loadDAEFVector
// Purpose       : load F vector (static contributions) for one instance for
//                 NEW DAE formulation
// Special Notes :
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
bool Instance::loadDAEFVector()
{

  bool bsuccess=true;
(*extData.daeFVectorPtr)[li_d] += staticContributions[admsNodeID_d];
(*extData.daeFVectorPtr)[li_g] += staticContributions[admsNodeID_g];
(*extData.daeFVectorPtr)[li_s] += staticContributions[admsNodeID_s];
(*extData.daeFVectorPtr)[li_di] += staticContributions[admsNodeID_di];
(*extData.daeFVectorPtr)[li_si] += staticContributions[admsNodeID_si];
(*extData.daeFVectorPtr)[li_sf] += staticContributions[admsNodeID_sf];

    (*extData.daeFVectorPtr)[li_BRA_sf_GND] += staticContributions[admsBRA_ID_sf_GND];

  if (loadLeadCurrent)
  {
    double * leadF = extData.nextLeadCurrFCompRawPtr;
    leadF[li_branch_id] = leadCurrentF[admsNodeID_d];
    leadF[li_branch_ig] = leadCurrentF[admsNodeID_g];
    leadF[li_branch_is] = leadCurrentF[admsNodeID_s];



    // here we have to do special things for BJTs, MOSFETs and 2-terminal
    // devices for power computation.

        double * solVec = extData.nextSolVectorRawPtr;
        double * junctionV = extData.nextJunctionVCompRawPtr;
        junctionV[li_branch_id] = solVec[li_d] - solVec[li_s];
        junctionV[li_branch_ig] = solVec[li_g] - solVec[li_s];

  }
  return bsuccess;
}

//-----------------------------------------------------------------------------
// Function      : Instance::loadDAEQVector
// Purpose       : load Q vector (dynamic contributions) for one instance for
//                 NEW DAE formulation
// Special Notes :
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
bool Instance::loadDAEQVector()
{
(*extData.daeQVectorPtr)[li_d] += dynamicContributions[admsNodeID_d];
(*extData.daeQVectorPtr)[li_g] += dynamicContributions[admsNodeID_g];
(*extData.daeQVectorPtr)[li_s] += dynamicContributions[admsNodeID_s];
(*extData.daeQVectorPtr)[li_di] += dynamicContributions[admsNodeID_di];
(*extData.daeQVectorPtr)[li_si] += dynamicContributions[admsNodeID_si];
(*extData.daeQVectorPtr)[li_sf] += dynamicContributions[admsNodeID_sf];

    (*extData.daeQVectorPtr)[li_BRA_sf_GND] += dynamicContributions[admsBRA_ID_sf_GND];

  if (loadLeadCurrent)
  {
    double * leadQ = extData.nextLeadCurrQCompRawPtr;
    leadQ[li_branch_id] = leadCurrentQ[admsNodeID_d];
    leadQ[li_branch_ig] = leadCurrentQ[admsNodeID_g];
    leadQ[li_branch_is] = leadCurrentQ[admsNodeID_s];


  }
  return true;
}


//-----------------------------------------------------------------------------
// Function      : Instance::updatePrimaryState
// Purpose       :
// Special Notes : In this initial implementation, does little more than
//                 call updateIntermediateVars()
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
bool Instance::updatePrimaryState()
{
  bool bsuccess = true;

  bsuccess = updateIntermediateVars();

  // if old DAE were implemented, we'd save dynamic contributions as state
  // here.


  return bsuccess;
}

//-----------------------------------------------------------------------------
// Function      : Instance::updateSecondaryState
// Purpose       :
// Special Notes : In this initial implementation, does nothing
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
bool Instance::updateSecondaryState()
{
  bool bsuccess = true;

  // were old DAE implemented, we'd pull dynamic contribution derivatives
  // out of state.

  return bsuccess;
}

//-----------------------------------------------------------------------------
// Function      : Instance::updateIntermediateVars
// Purpose       : update intermediate variables for one mvs_2_0_0_etsoi instance
// Special Notes :
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
bool Instance::updateIntermediateVars()
{

  bool bsuccess=true;
  Linear::Vector * solVectorPtr = extData.nextSolVectorPtr;

  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
  {
    Xyce::dout() << std::endl << subsection_divider << std::endl;
    Xyce::dout() << "  In ADMSmvs_2_0_0_etsoi::Instance::updateIntermediateVars\n\n";
    Xyce::dout() << "  name = " << getName() << std::endl;
  }

  // Local variables
  double Id=0.0;
     double d_Id_dV_sf_GND=0.0;
     double d_Id_dV_di_GND=0.0;
     double d_Id_dV_si_GND=0.0;
  double vx0=0.0;
  double Fsat=0.0;
     double d_Fsat_dV_di_GND=0.0;
     double d_Fsat_dV_si_GND=0.0;
     double d_Fsat_dV_sf_GND=0.0;
  double Vdsatbeta=0.0;
     double d_Vdsatbeta_dV_di_GND=0.0;
     double d_Vdsatbeta_dV_si_GND=0.0;
     double d_Vdsatbeta_dV_sf_GND=0.0;
  double Vdsat=0.0;
     double d_Vdsat_dV_di_GND=0.0;
     double d_Vdsat_dV_si_GND=0.0;
     double d_Vdsat_dV_sf_GND=0.0;
  double f1=0.0;
     double d_f1_dV_di_GND=0.0;
     double d_f1_dV_si_GND=0.0;
     double d_f1_dV_sf_GND=0.0;
  double n=0.0;
     double d_n_dV_di_GND=0.0;
     double d_n_dV_si_GND=0.0;
  double Cgc=0.0;
     double d_Cgc_dV_sf_GND=0.0;
     double d_Cgc_dV_di_GND=0.0;
     double d_Cgc_dV_si_GND=0.0;
  double Cstern=0.0;
     double d_Cstern_dV_sf_GND=0.0;
     double d_Cstern_dV_di_GND=0.0;
     double d_Cstern_dV_si_GND=0.0;
  double xav=0.0;
     double d_xav_dV_sf_GND=0.0;
     double d_xav_dV_di_GND=0.0;
     double d_xav_dV_si_GND=0.0;
  double QB=0.0;
  double Qx0=0.0;
     double d_Qx0_dV_sf_GND=0.0;
     double d_Qx0_dV_di_GND=0.0;
     double d_Qx0_dV_si_GND=0.0;
  double Tx=0.0;
     double d_Tx_dV_di_GND=0.0;
     double d_Tx_dV_si_GND=0.0;
  double Lcrit=0.0;
     double d_Lcrit_dV_di_GND=0.0;
     double d_Lcrit_dV_si_GND=0.0;
  double Lcrit_sat=0.0;
  double Lcrit_lin=0.0;
  double f2=0.0;
     double d_f2_dV_di_GND=0.0;
     double d_f2_dV_si_GND=0.0;
  double Vdsatbeta2=0.0;
     double d_Vdsatbeta2_dV_di_GND=0.0;
     double d_Vdsatbeta2_dV_si_GND=0.0;
  double Vdsat2=0.0;
  double Fd=0.0;
     double d_Fd_dV_sf_GND=0.0;
     double d_Fd_dV_di_GND=0.0;
     double d_Fd_dV_si_GND=0.0;
  double Fs=0.0;
     double d_Fs_dV_sf_GND=0.0;
  double Fd_delta4=0.0;
     double d_Fd_delta4_dV_sf_GND=0.0;
     double d_Fd_delta4_dV_di_GND=0.0;
     double d_Fd_delta4_dV_si_GND=0.0;
  double Fd_delta2=0.0;
     double d_Fd_delta2_dV_sf_GND=0.0;
     double d_Fd_delta2_dV_di_GND=0.0;
     double d_Fd_delta2_dV_si_GND=0.0;
  double Fs_delta4=0.0;
     double d_Fs_delta4_dV_sf_GND=0.0;
  double Fs_delta2=0.0;
     double d_Fs_delta2_dV_sf_GND=0.0;
  double lnoneplusEd=0.0;
     double d_lnoneplusEd_dV_sf_GND=0.0;
     double d_lnoneplusEd_dV_di_GND=0.0;
     double d_lnoneplusEd_dV_si_GND=0.0;
  double lnoneplusEs=0.0;
     double d_lnoneplusEs_dV_sf_GND=0.0;
  double Ed_delta2=0.0;
     double d_Ed_delta2_dV_sf_GND=0.0;
     double d_Ed_delta2_dV_di_GND=0.0;
     double d_Ed_delta2_dV_si_GND=0.0;
  double Es_delta2=0.0;
     double d_Es_delta2_dV_sf_GND=0.0;
  double Rd=0.0;
  double Rs=0.0;
  double Leff=0.0;
  double N2D=0.0;
  double lambda=0.0;
  double vT=0.0;
  double vT_delta4_int=0.0;
  double mC_delta4=0.0;
  double mD_delta4=0.0;
  double vT_delta2_int=0.0;
  double mC_delta2=0.0;
  double mD_delta2=0.0;
  double hbar=0.0;
  double kT=0.0;
  double phit=0.0;
  double dir=0.0;
  double Vgsi=0.0;
     double d_Vgsi_dV_di_GND=0.0;
     double d_Vgsi_dV_g_GND=0.0;
     double d_Vgsi_dV_si_GND=0.0;
  double Vdsi=0.0;
     double d_Vdsi_dV_di_GND=0.0;
     double d_Vdsi_dV_si_GND=0.0;
  double Vgs=0.0;
  double Vds=0.0;
  double Vgdraw=0.0;
     double d_Vgdraw_dV_g_GND=0.0;
     double d_Vgdraw_dV_di_GND=0.0;
  double Vgsraw=0.0;
     double d_Vgsraw_dV_g_GND=0.0;
     double d_Vgsraw_dV_si_GND=0.0;


  // set the sizes of the Fad arrays:

  if (probeVars.size() != (7))
  {
    probeVars.resize(7);
    d_probeVars.resize(7);
    for (int i=0;i<7;i++)
    {
      d_probeVars[i].resize(7);
      for (int j=0;j<7;j++)
        d_probeVars[i][j]=0.0;
    }
    staticContributions.resize(6+1);
    d_staticContributions.resize(6+1);
    for (int i=0;i<6+1;i++)
      d_staticContributions[i].resize(7);
    dynamicContributions.resize(6+1);
    d_dynamicContributions.resize(6+1);
    for (int i=0;i<6+1;i++)
      d_dynamicContributions[i].resize(7);
  }


  // initialize contributions to zero (automatically sets derivatives to zero)
  for (int i=0; i < 6+1 ; ++i)
  {
     staticContributions[i]=0;
     for (int j=0;j<7;j++)
        d_staticContributions[i][j] = 0.0;
     dynamicContributions[i]=0;
     for (int j=0;j<7;j++)
        d_dynamicContributions[i][j] = 0.0;
  }

  // extract solution variables and set as Fad independent variables.
probeVars[admsProbeID_V_sf_GND] = (*solVectorPtr)[li_sf];
d_probeVars[admsProbeID_V_sf_GND][admsProbeID_V_sf_GND] = 1.0;
probeVars[admsProbeID_V_s_GND] = (*solVectorPtr)[li_s];
d_probeVars[admsProbeID_V_s_GND][admsProbeID_V_s_GND] = 1.0;
probeVars[admsProbeID_V_d_GND] = (*solVectorPtr)[li_d];
d_probeVars[admsProbeID_V_d_GND][admsProbeID_V_d_GND] = 1.0;
probeVars[admsProbeID_V_di_GND] = (*solVectorPtr)[li_di];
d_probeVars[admsProbeID_V_di_GND][admsProbeID_V_di_GND] = 1.0;
probeVars[admsProbeID_V_si_GND] = (*solVectorPtr)[li_si];
d_probeVars[admsProbeID_V_si_GND][admsProbeID_V_si_GND] = 1.0;
probeVars[admsProbeID_V_g_GND] = (*solVectorPtr)[li_g];
d_probeVars[admsProbeID_V_g_GND][admsProbeID_V_g_GND] = 1.0;
probeVars[admsProbeID_I_sf_GND] = (*solVectorPtr)[li_BRA_sf_GND];
d_probeVars[admsProbeID_I_sf_GND][admsProbeID_I_sf_GND] = 1.0;
// -- code converted from analog/code block

d_Vgsraw_dV_si_GND = (model_.type)*(-d_probeVars[admsProbeID_V_si_GND][admsProbeID_V_si_GND]);
d_Vgsraw_dV_g_GND = (model_.type)*d_probeVars[admsProbeID_V_g_GND][admsProbeID_V_g_GND];
Vgsraw = ((model_.type)*((probeVars[admsProbeID_V_g_GND])-(probeVars[admsProbeID_V_si_GND])));

d_Vgdraw_dV_di_GND = (model_.type)*(-d_probeVars[admsProbeID_V_di_GND][admsProbeID_V_di_GND]);
d_Vgdraw_dV_g_GND = (model_.type)*d_probeVars[admsProbeID_V_g_GND][admsProbeID_V_g_GND];
Vgdraw = ((model_.type)*((probeVars[admsProbeID_V_g_GND])-(probeVars[admsProbeID_V_di_GND])));
if ((Vgsraw>=Vgdraw))
{
Vds = ((model_.type)*((probeVars[admsProbeID_V_d_GND])-(probeVars[admsProbeID_V_s_GND])));
Vgs = ((model_.type)*((probeVars[admsProbeID_V_g_GND])-(probeVars[admsProbeID_V_s_GND])));

d_Vdsi_dV_si_GND = (model_.type)*(-d_probeVars[admsProbeID_V_si_GND][admsProbeID_V_si_GND]);
d_Vdsi_dV_di_GND = (model_.type)*d_probeVars[admsProbeID_V_di_GND][admsProbeID_V_di_GND];
Vdsi = ((model_.type)*((probeVars[admsProbeID_V_di_GND])-(probeVars[admsProbeID_V_si_GND])));

d_Vgsi_dV_di_GND =  0.0;
d_Vgsi_dV_si_GND = d_Vgsraw_dV_si_GND;
d_Vgsi_dV_g_GND = d_Vgsraw_dV_g_GND;
Vgsi = Vgsraw;
dir = 1;
}
else
{
Vds = ((model_.type)*((probeVars[admsProbeID_V_s_GND])-(probeVars[admsProbeID_V_d_GND])));
Vgs = ((model_.type)*((probeVars[admsProbeID_V_g_GND])-(probeVars[admsProbeID_V_d_GND])));

d_Vdsi_dV_di_GND = (model_.type)*(-d_probeVars[admsProbeID_V_di_GND][admsProbeID_V_di_GND]);
d_Vdsi_dV_si_GND = (model_.type)*d_probeVars[admsProbeID_V_si_GND][admsProbeID_V_si_GND];
Vdsi = ((model_.type)*((probeVars[admsProbeID_V_si_GND])-(probeVars[admsProbeID_V_di_GND])));

d_Vgsi_dV_si_GND =  0.0;
d_Vgsi_dV_di_GND = d_Vgdraw_dV_di_GND;
d_Vgsi_dV_g_GND = d_Vgdraw_dV_g_GND;
Vgsi = Vgdraw;
dir = (-1);
}
phit = ((1.3806503e-23*(model_.Tjun))/1.6021766208e-19);
kT = (1.3806503e-23*(model_.Tjun));
hbar = (6.62607004081e-34/(2.0*3.14159265358979323846));
mD_delta2 = ((2.0*(model_.mt))*9.10938215e-31);
mC_delta2 = ((4.0*(model_.mt))*9.10938215e-31);
{
double value_sqrt_0 = sqrt(((((2.0*kT)/3.14159265358979323846)*mC_delta2)/(mD_delta2*mD_delta2)));
vT_delta2_int = value_sqrt_0;
}
{
double value_sqrt_0 = sqrt(((model_.mt)*(model_.ml)));
mD_delta4 = ((4.0*value_sqrt_0)*9.10938215e-31);
}
{
double value_sqrt_0 = sqrt((model_.mt));
double value_sqrt_1 = sqrt((model_.ml));
double value_sqrt_2 = sqrt((model_.mt));
double value_sqrt_3 = sqrt((model_.ml));
mC_delta4 = (((4.0*(value_sqrt_0+value_sqrt_1))*(value_sqrt_2+value_sqrt_3))*9.10938215e-31);
}
{
double value_sqrt_0 = sqrt(((((2.0*kT)/3.14159265358979323846)*mC_delta4)/(mD_delta4*mD_delta4)));
vT_delta4_int = value_sqrt_0;
}
vT = (((model_.nu)*vT_delta2_int)+((1.0-(model_.nu))*vT_delta4_int));
lambda = (((2.0*phit)*(model_.mu_eff))/vT);
N2D = ((mD_delta2/((3.14159265358979323846*hbar)*hbar))*kT);
Leff = ((model_.Lgdr)-(model_.dLg));
Rs = ((model_.Rs0)/(model_.W));
Rd = Rs;

d_Es_delta2_dV_sf_GND = (d_probeVars[admsProbeID_V_sf_GND][admsProbeID_V_sf_GND]/phit);
Es_delta2 = (((model_.energy_diff_volt)+(probeVars[admsProbeID_V_sf_GND]))/phit);

d_Ed_delta2_dV_si_GND = ((-d_Vdsi_dV_si_GND)/phit);
d_Ed_delta2_dV_di_GND = ((-d_Vdsi_dV_di_GND)/phit);
d_Ed_delta2_dV_sf_GND = (d_probeVars[admsProbeID_V_sf_GND][admsProbeID_V_sf_GND]/phit);
Ed_delta2 = ((((model_.energy_diff_volt)+(probeVars[admsProbeID_V_sf_GND]))-Vdsi)/phit);
if ((Es_delta2<=40))
{
{
double value_exp_0 = exp(Es_delta2);
double value_log_1 = log((1.0+value_exp_0));
double  deriv_exp_0_d0 = value_exp_0;
double  deriv_log_1_d0 = (1.0/(1.0+value_exp_0));

d_lnoneplusEs_dV_sf_GND = (deriv_log_1_d0*((deriv_exp_0_d0*(d_Es_delta2_dV_sf_GND))));
lnoneplusEs = value_log_1;
}
}
else
{

d_lnoneplusEs_dV_sf_GND = d_Es_delta2_dV_sf_GND;
lnoneplusEs = Es_delta2;
}
if ((Ed_delta2<=40))
{
{
double value_exp_0 = exp(Ed_delta2);
double value_log_1 = log((1.0+value_exp_0));
double  deriv_exp_0_d0 = value_exp_0;
double  deriv_log_1_d0 = (1.0/(1.0+value_exp_0));

d_lnoneplusEd_dV_si_GND = (deriv_log_1_d0*((deriv_exp_0_d0*(d_Ed_delta2_dV_si_GND))));
d_lnoneplusEd_dV_di_GND = (deriv_log_1_d0*((deriv_exp_0_d0*(d_Ed_delta2_dV_di_GND))));
d_lnoneplusEd_dV_sf_GND = (deriv_log_1_d0*((deriv_exp_0_d0*(d_Ed_delta2_dV_sf_GND))));
lnoneplusEd = value_log_1;
}
}
else
{

d_lnoneplusEd_dV_si_GND = d_Ed_delta2_dV_si_GND;
d_lnoneplusEd_dV_di_GND = d_Ed_delta2_dV_di_GND;
d_lnoneplusEd_dV_sf_GND = d_Ed_delta2_dV_sf_GND;
lnoneplusEd = Ed_delta2;
}

d_Fs_delta2_dV_sf_GND = d_lnoneplusEs_dV_sf_GND;
Fs_delta2 = lnoneplusEs;

d_Fs_delta4_dV_sf_GND = (d_Fs_delta2_dV_sf_GND*(1.0-(model_.nu))/(model_.nu));
Fs_delta4 = ((Fs_delta2*(1.0-(model_.nu)))/(model_.nu));

d_Fd_delta2_dV_si_GND = d_lnoneplusEd_dV_si_GND;
d_Fd_delta2_dV_di_GND = d_lnoneplusEd_dV_di_GND;
d_Fd_delta2_dV_sf_GND = d_lnoneplusEd_dV_sf_GND;
Fd_delta2 = lnoneplusEd;

d_Fd_delta4_dV_si_GND = (d_Fd_delta2_dV_si_GND*(1.0-(model_.nu))/(model_.nu));
d_Fd_delta4_dV_di_GND = (d_Fd_delta2_dV_di_GND*(1.0-(model_.nu))/(model_.nu));
d_Fd_delta4_dV_sf_GND = (d_Fd_delta2_dV_sf_GND*(1.0-(model_.nu))/(model_.nu));
Fd_delta4 = ((Fd_delta2*(1.0-(model_.nu)))/(model_.nu));

d_Fs_dV_sf_GND = (d_Fs_delta2_dV_sf_GND+d_Fs_delta4_dV_sf_GND);
Fs = (Fs_delta2+Fs_delta4);

d_Fd_dV_si_GND = (d_Fd_delta2_dV_si_GND+d_Fd_delta4_dV_si_GND);
d_Fd_dV_di_GND = (d_Fd_delta2_dV_di_GND+d_Fd_delta4_dV_di_GND);
d_Fd_dV_sf_GND = (d_Fd_delta2_dV_sf_GND+d_Fd_delta4_dV_sf_GND);
Fd = (Fd_delta2+Fd_delta4);
Vdsat2 = ((model_.theta)*phit);
{
double value_fabs_0 = fabs((Vdsi/Vdsat2));
double value_pow_1 = pow(value_fabs_0,(model_.beta));
double  deriv_fabs_0_d0 = ((((Vdsi/Vdsat2))>=0)?(+1.0):(-1.0));
double  deriv_pow_1_d0 = ((value_fabs_0 == 0.0)?0.0:(value_pow_1*(model_.beta)/value_fabs_0));

d_Vdsatbeta2_dV_si_GND = (deriv_pow_1_d0*((deriv_fabs_0_d0*((d_Vdsi_dV_si_GND/Vdsat2)))));
d_Vdsatbeta2_dV_di_GND = (deriv_pow_1_d0*((deriv_fabs_0_d0*((d_Vdsi_dV_di_GND/Vdsat2)))));
Vdsatbeta2 = value_pow_1;
}
{
double value_fabs_0 = fabs((Vdsi/Vdsat2));
double value_pow_1 = pow((1.0+Vdsatbeta2),(1.0/(model_.beta)));
double  deriv_fabs_0_d0 = ((((Vdsi/Vdsat2))>=0)?(+1.0):(-1.0));
double  deriv_pow_1_d0 = (((1.0+Vdsatbeta2) == 0.0)?0.0:(value_pow_1*(1.0/(model_.beta))/(1.0+Vdsatbeta2)));

d_f2_dV_si_GND = ((value_pow_1*(deriv_fabs_0_d0*((d_Vdsi_dV_si_GND/Vdsat2)))-value_fabs_0*(deriv_pow_1_d0*(d_Vdsatbeta2_dV_si_GND)))/value_pow_1/value_pow_1);
d_f2_dV_di_GND = ((value_pow_1*(deriv_fabs_0_d0*((d_Vdsi_dV_di_GND/Vdsat2)))-value_fabs_0*(deriv_pow_1_d0*(d_Vdsatbeta2_dV_di_GND)))/value_pow_1/value_pow_1);
f2 = (value_fabs_0/value_pow_1);
}
Lcrit_lin = Leff;
Lcrit_sat = ((model_.ksee)*Leff);

d_Lcrit_dV_si_GND = ((-d_f2_dV_si_GND)*Lcrit_lin+d_f2_dV_si_GND*Lcrit_sat);
d_Lcrit_dV_di_GND = ((-d_f2_dV_di_GND)*Lcrit_lin+d_f2_dV_di_GND*Lcrit_sat);
Lcrit = (((1.0-f2)*Lcrit_lin)+(f2*Lcrit_sat));

d_Tx_dV_si_GND = (-lambda*d_Lcrit_dV_si_GND/(lambda+Lcrit)/(lambda+Lcrit));
d_Tx_dV_di_GND = (-lambda*d_Lcrit_dV_di_GND/(lambda+Lcrit)/(lambda+Lcrit));
Tx = (lambda/(lambda+Lcrit));

d_Qx0_dV_si_GND = (((-1.6021766208e-19)*N2D)/2.0)*(Fs*(-d_Tx_dV_si_GND)+(Fd*d_Tx_dV_si_GND+d_Fd_dV_si_GND*Tx));
d_Qx0_dV_di_GND = (((-1.6021766208e-19)*N2D)/2.0)*(Fs*(-d_Tx_dV_di_GND)+(Fd*d_Tx_dV_di_GND+d_Fd_dV_di_GND*Tx));
d_Qx0_dV_sf_GND = (((-1.6021766208e-19)*N2D)/2.0)*(d_Fs_dV_sf_GND*(2.0-Tx)+d_Fd_dV_sf_GND*Tx);
Qx0 = ((((-1.6021766208e-19)*N2D)/2.0)*((Fs*(2.0-Tx))+(Fd*Tx)));
{
double value_fabs_0 = fabs(((model_.B)/(model_.dqm0)));
double value_pow_1 = pow(value_fabs_0,3.0);
QB = value_pow_1;
}
{
double value_fabs_0 = fabs(Qx0);
double value_pow_1 = pow((QB+((11.0/32.0)*value_fabs_0)),(1/3.0));
double  deriv_fabs_0_d0 = (((Qx0)>=0)?(+1.0):(-1.0));
double  deriv_pow_1_d0 = (((QB+((11.0/32.0)*value_fabs_0)) == 0.0)?0.0:(value_pow_1*(1/3.0)/(QB+((11.0/32.0)*value_fabs_0))));

d_xav_dV_si_GND = (-(model_.B)*(deriv_pow_1_d0*((11.0/32.0)*(deriv_fabs_0_d0*(d_Qx0_dV_si_GND))))/value_pow_1/value_pow_1);
d_xav_dV_di_GND = (-(model_.B)*(deriv_pow_1_d0*((11.0/32.0)*(deriv_fabs_0_d0*(d_Qx0_dV_di_GND))))/value_pow_1/value_pow_1);
d_xav_dV_sf_GND = (-(model_.B)*(deriv_pow_1_d0*((11.0/32.0)*(deriv_fabs_0_d0*(d_Qx0_dV_sf_GND))))/value_pow_1/value_pow_1);
xav = ((model_.B)/value_pow_1);
}

d_Cstern_dV_si_GND = (-((model_.eps)*8.854187817e-12)*d_xav_dV_si_GND/xav/xav);
d_Cstern_dV_di_GND = (-((model_.eps)*8.854187817e-12)*d_xav_dV_di_GND/xav/xav);
d_Cstern_dV_sf_GND = (-((model_.eps)*8.854187817e-12)*d_xav_dV_sf_GND/xav/xav);
Cstern = (((model_.eps)*8.854187817e-12)/xav);

d_Cgc_dV_si_GND = ((((model_.Cins)+Cstern)*(model_.Cins)*d_Cstern_dV_si_GND-((model_.Cins)*Cstern)*d_Cstern_dV_si_GND)/((model_.Cins)+Cstern)/((model_.Cins)+Cstern));
d_Cgc_dV_di_GND = ((((model_.Cins)+Cstern)*(model_.Cins)*d_Cstern_dV_di_GND-((model_.Cins)*Cstern)*d_Cstern_dV_di_GND)/((model_.Cins)+Cstern)/((model_.Cins)+Cstern));
d_Cgc_dV_sf_GND = ((((model_.Cins)+Cstern)*(model_.Cins)*d_Cstern_dV_sf_GND-((model_.Cins)*Cstern)*d_Cstern_dV_sf_GND)/((model_.Cins)+Cstern)/((model_.Cins)+Cstern));
Cgc = (((model_.Cins)*Cstern)/((model_.Cins)+Cstern));
{
double value_fabs_0 = fabs(((model_.nd)*Vdsi));
double  deriv_fabs_0_d0 = (((((model_.nd)*Vdsi))>=0)?(+1.0):(-1.0));

d_n_dV_si_GND = (deriv_fabs_0_d0*((model_.nd)*d_Vdsi_dV_si_GND));
d_n_dV_di_GND = (deriv_fabs_0_d0*((model_.nd)*d_Vdsi_dV_di_GND));
n = ((model_.n0)+value_fabs_0);
}
// V(sf,GND) <+ ((((Vgsi+(delta*Vdsi))+(Qx0/Cgc))/n))
d_staticContributions[admsBRA_ID_sf_GND][admsProbeID_V_sf_GND] += (((Cgc*d_Qx0_dV_sf_GND-Qx0*d_Cgc_dV_sf_GND)/Cgc/Cgc)/n);
d_staticContributions[admsBRA_ID_sf_GND][admsProbeID_V_si_GND] += ((n*((d_Vgsi_dV_si_GND+(model_.delta)*d_Vdsi_dV_si_GND)+((Cgc*d_Qx0_dV_si_GND-Qx0*d_Cgc_dV_si_GND)/Cgc/Cgc))-((Vgsi+((model_.delta)*Vdsi))+(Qx0/Cgc))*d_n_dV_si_GND)/n/n);
d_staticContributions[admsBRA_ID_sf_GND][admsProbeID_V_g_GND] += (d_Vgsi_dV_g_GND/n);
d_staticContributions[admsBRA_ID_sf_GND][admsProbeID_V_di_GND] += ((n*((d_Vgsi_dV_di_GND+(model_.delta)*d_Vdsi_dV_di_GND)+((Cgc*d_Qx0_dV_di_GND-Qx0*d_Cgc_dV_di_GND)/Cgc/Cgc))-((Vgsi+((model_.delta)*Vdsi))+(Qx0/Cgc))*d_n_dV_di_GND)/n/n);
staticContributions[admsBRA_ID_sf_GND] += (((Vgsi+((model_.delta)*Vdsi))+(Qx0/Cgc))/n);

d_f1_dV_sf_GND = (((2.0*Fs)*((2.0-Tx)*d_Fs_dV_sf_GND+Tx*d_Fd_dV_sf_GND)-(((2.0-Tx)*Fs)+(Tx*Fd))*2.0*d_Fs_dV_sf_GND)/(2.0*Fs)/(2.0*Fs));
d_f1_dV_si_GND = (((-d_Tx_dV_si_GND)*Fs+(Tx*d_Fd_dV_si_GND+d_Tx_dV_si_GND*Fd))/(2.0*Fs));
d_f1_dV_di_GND = (((-d_Tx_dV_di_GND)*Fs+(Tx*d_Fd_dV_di_GND+d_Tx_dV_di_GND*Fd))/(2.0*Fs));
f1 = ((((2.0-Tx)*Fs)+(Tx*Fd))/(2.0*Fs));

d_Vdsat_dV_sf_GND = (((2.0*phit)*(lambda+Leff))/(lambda+((2.0*(model_.ksee))*Leff)))*d_f1_dV_sf_GND;
d_Vdsat_dV_si_GND = (((2.0*phit)*(lambda+Leff))/(lambda+((2.0*(model_.ksee))*Leff)))*d_f1_dV_si_GND;
d_Vdsat_dV_di_GND = (((2.0*phit)*(lambda+Leff))/(lambda+((2.0*(model_.ksee))*Leff)))*d_f1_dV_di_GND;
Vdsat = ((((2.0*phit)*(lambda+Leff))/(lambda+((2.0*(model_.ksee))*Leff)))*f1);
{
double value_fabs_0 = fabs((Vdsi/Vdsat));
double value_pow_1 = pow(value_fabs_0,(model_.beta));
double  deriv_fabs_0_d0 = ((((Vdsi/Vdsat))>=0)?(+1.0):(-1.0));
double  deriv_pow_1_d0 = ((value_fabs_0 == 0.0)?0.0:(value_pow_1*(model_.beta)/value_fabs_0));

d_Vdsatbeta_dV_sf_GND = (deriv_pow_1_d0*((deriv_fabs_0_d0*((-Vdsi*d_Vdsat_dV_sf_GND/Vdsat/Vdsat)))));
d_Vdsatbeta_dV_si_GND = (deriv_pow_1_d0*((deriv_fabs_0_d0*(((Vdsat*d_Vdsi_dV_si_GND-Vdsi*d_Vdsat_dV_si_GND)/Vdsat/Vdsat)))));
d_Vdsatbeta_dV_di_GND = (deriv_pow_1_d0*((deriv_fabs_0_d0*(((Vdsat*d_Vdsi_dV_di_GND-Vdsi*d_Vdsat_dV_di_GND)/Vdsat/Vdsat)))));
Vdsatbeta = value_pow_1;
}
{
double value_fabs_0 = fabs((Vdsi/Vdsat));
double value_pow_1 = pow((1.0+Vdsatbeta),(1.0/(model_.beta)));
double  deriv_fabs_0_d0 = ((((Vdsi/Vdsat))>=0)?(+1.0):(-1.0));
double  deriv_pow_1_d0 = (((1.0+Vdsatbeta) == 0.0)?0.0:(value_pow_1*(1.0/(model_.beta))/(1.0+Vdsatbeta)));

d_Fsat_dV_sf_GND = ((value_pow_1*(deriv_fabs_0_d0*((-Vdsi*d_Vdsat_dV_sf_GND/Vdsat/Vdsat)))-value_fabs_0*(deriv_pow_1_d0*(d_Vdsatbeta_dV_sf_GND)))/value_pow_1/value_pow_1);
d_Fsat_dV_si_GND = ((value_pow_1*(deriv_fabs_0_d0*(((Vdsat*d_Vdsi_dV_si_GND-Vdsi*d_Vdsat_dV_si_GND)/Vdsat/Vdsat)))-value_fabs_0*(deriv_pow_1_d0*(d_Vdsatbeta_dV_si_GND)))/value_pow_1/value_pow_1);
d_Fsat_dV_di_GND = ((value_pow_1*(deriv_fabs_0_d0*(((Vdsat*d_Vdsi_dV_di_GND-Vdsi*d_Vdsat_dV_di_GND)/Vdsat/Vdsat)))-value_fabs_0*(deriv_pow_1_d0*(d_Vdsatbeta_dV_di_GND)))/value_pow_1/value_pow_1);
Fsat = (value_fabs_0/value_pow_1);
}
vx0 = ((vT*lambda)/(lambda+((2.0*(model_.ksee))*Leff)));
{
double value_fabs_0 = fabs(Qx0);
double  deriv_fabs_0_d0 = (((Qx0)>=0)?(+1.0):(-1.0));

d_Id_dV_si_GND = (value_fabs_0*d_Fsat_dV_si_GND+(deriv_fabs_0_d0*(d_Qx0_dV_si_GND))*Fsat)*vx0*(model_.W);
d_Id_dV_di_GND = (value_fabs_0*d_Fsat_dV_di_GND+(deriv_fabs_0_d0*(d_Qx0_dV_di_GND))*Fsat)*vx0*(model_.W);
d_Id_dV_sf_GND = (value_fabs_0*d_Fsat_dV_sf_GND+(deriv_fabs_0_d0*(d_Qx0_dV_sf_GND))*Fsat)*vx0*(model_.W);
Id = (((value_fabs_0*Fsat)*vx0)*(model_.W));
}
// I(di,si) <+ (((type*dir)*Id))
staticContributions[admsNodeID_di] += (((model_.type)*dir)*Id);
d_staticContributions[admsNodeID_di][admsProbeID_V_si_GND] += ((model_.type)*dir)*d_Id_dV_si_GND;
d_staticContributions[admsNodeID_di][admsProbeID_V_di_GND] += ((model_.type)*dir)*d_Id_dV_di_GND;
d_staticContributions[admsNodeID_di][admsProbeID_V_sf_GND] += ((model_.type)*dir)*d_Id_dV_sf_GND;
staticContributions[admsNodeID_si] -= (((model_.type)*dir)*Id);
d_staticContributions[admsNodeID_si][admsProbeID_V_si_GND] -= ((model_.type)*dir)*d_Id_dV_si_GND;
d_staticContributions[admsNodeID_si][admsProbeID_V_di_GND] -= ((model_.type)*dir)*d_Id_dV_di_GND;
d_staticContributions[admsNodeID_si][admsProbeID_V_sf_GND] -= ((model_.type)*dir)*d_Id_dV_sf_GND;
// I(d,di) <+ (((V(d,GND)-V(di,GND))/Rd))
staticContributions[admsNodeID_d] += (((probeVars[admsProbeID_V_d_GND])-(probeVars[admsProbeID_V_di_GND]))/Rd);
d_staticContributions[admsNodeID_d][admsProbeID_V_di_GND] += ((-d_probeVars[admsProbeID_V_di_GND][admsProbeID_V_di_GND])/Rd);
d_staticContributions[admsNodeID_d][admsProbeID_V_d_GND] += (d_probeVars[admsProbeID_V_d_GND][admsProbeID_V_d_GND]/Rd);
staticContributions[admsNodeID_di] -= (((probeVars[admsProbeID_V_d_GND])-(probeVars[admsProbeID_V_di_GND]))/Rd);
d_staticContributions[admsNodeID_di][admsProbeID_V_di_GND] -= ((-d_probeVars[admsProbeID_V_di_GND][admsProbeID_V_di_GND])/Rd);
d_staticContributions[admsNodeID_di][admsProbeID_V_d_GND] -= (d_probeVars[admsProbeID_V_d_GND][admsProbeID_V_d_GND]/Rd);
// I(si,s) <+ (((V(si,GND)-V(s,GND))/Rs))
staticContributions[admsNodeID_si] += (((probeVars[admsProbeID_V_si_GND])-(probeVars[admsProbeID_V_s_GND]))/Rs);
d_staticContributions[admsNodeID_si][admsProbeID_V_s_GND] += ((-d_probeVars[admsProbeID_V_s_GND][admsProbeID_V_s_GND])/Rs);
d_staticContributions[admsNodeID_si][admsProbeID_V_si_GND] += (d_probeVars[admsProbeID_V_si_GND][admsProbeID_V_si_GND]/Rs);
staticContributions[admsNodeID_s] -= (((probeVars[admsProbeID_V_si_GND])-(probeVars[admsProbeID_V_s_GND]))/Rs);
d_staticContributions[admsNodeID_s][admsProbeID_V_s_GND] -= ((-d_probeVars[admsProbeID_V_s_GND][admsProbeID_V_s_GND])/Rs);
d_staticContributions[admsNodeID_s][admsProbeID_V_si_GND] -= (d_probeVars[admsProbeID_V_si_GND][admsProbeID_V_si_GND]/Rs);

          // Additional term resulting from contributions into V(sf,GND)
staticContributions[admsNodeID_sf] += probeVars[admsProbeID_I_sf_GND];
d_staticContributions[admsNodeID_sf][admsProbeID_I_sf_GND] += d_probeVars[admsProbeID_I_sf_GND][admsProbeID_I_sf_GND];
  // Final term for branch equation admsBRA_ID_sf_GND 
// Derivative of this term with respect to node is +/-1
// Handling of that derivative is done explicitly in the loadDAEdFdX method
  staticContributions[admsBRA_ID_sf_GND] -= (*solVectorPtr)[li_sf];


  // -- endcode converted from analog/code block
  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
  {
    Xyce::dout() << " probeVars[admsProbeID_V_sf_GND] =  "
         <<probeVars[admsProbeID_V_sf_GND] << std::endl;
    Xyce::dout() << " probeVars[admsProbeID_V_s_GND] =  "
         <<probeVars[admsProbeID_V_s_GND] << std::endl;
    Xyce::dout() << " probeVars[admsProbeID_V_d_GND] =  "
         <<probeVars[admsProbeID_V_d_GND] << std::endl;
    Xyce::dout() << " probeVars[admsProbeID_V_di_GND] =  "
         <<probeVars[admsProbeID_V_di_GND] << std::endl;
    Xyce::dout() << " probeVars[admsProbeID_V_si_GND] =  "
         <<probeVars[admsProbeID_V_si_GND] << std::endl;
    Xyce::dout() << " probeVars[admsProbeID_V_g_GND] =  "
         <<probeVars[admsProbeID_V_g_GND] << std::endl;
    Xyce::dout() << " staticContributions[admsNodeID_d] =  "
         <<staticContributions[admsNodeID_d] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_d].dx(admsProbeID_V_sf_GND) =  " <<d_staticContributions[admsNodeID_d][admsProbeID_V_sf_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_d].dx(admsProbeID_V_s_GND) =  " <<d_staticContributions[admsNodeID_d][admsProbeID_V_s_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_d].dx(admsProbeID_V_d_GND) =  " <<d_staticContributions[admsNodeID_d][admsProbeID_V_d_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_d].dx(admsProbeID_V_di_GND) =  " <<d_staticContributions[admsNodeID_d][admsProbeID_V_di_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_d].dx(admsProbeID_V_si_GND) =  " <<d_staticContributions[admsNodeID_d][admsProbeID_V_si_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_d].dx(admsProbeID_V_g_GND) =  " <<d_staticContributions[admsNodeID_d][admsProbeID_V_g_GND] << std::endl;
    Xyce::dout() << " dynamicContributions[admsNodeID_d] =  "
         <<dynamicContributions[admsNodeID_d] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_d].dx(admsProbeID_V_sf_GND) =  " <<d_dynamicContributions[admsNodeID_d][admsProbeID_V_sf_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_d].dx(admsProbeID_V_s_GND) =  " <<d_dynamicContributions[admsNodeID_d][admsProbeID_V_s_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_d].dx(admsProbeID_V_d_GND) =  " <<d_dynamicContributions[admsNodeID_d][admsProbeID_V_d_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_d].dx(admsProbeID_V_di_GND) =  " <<d_dynamicContributions[admsNodeID_d][admsProbeID_V_di_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_d].dx(admsProbeID_V_si_GND) =  " <<d_dynamicContributions[admsNodeID_d][admsProbeID_V_si_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_d].dx(admsProbeID_V_g_GND) =  " <<d_dynamicContributions[admsNodeID_d][admsProbeID_V_g_GND] << std::endl;
    Xyce::dout() << " staticContributions[admsNodeID_g] =  "
         <<staticContributions[admsNodeID_g] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_g].dx(admsProbeID_V_sf_GND) =  " <<d_staticContributions[admsNodeID_g][admsProbeID_V_sf_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_g].dx(admsProbeID_V_s_GND) =  " <<d_staticContributions[admsNodeID_g][admsProbeID_V_s_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_g].dx(admsProbeID_V_d_GND) =  " <<d_staticContributions[admsNodeID_g][admsProbeID_V_d_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_g].dx(admsProbeID_V_di_GND) =  " <<d_staticContributions[admsNodeID_g][admsProbeID_V_di_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_g].dx(admsProbeID_V_si_GND) =  " <<d_staticContributions[admsNodeID_g][admsProbeID_V_si_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_g].dx(admsProbeID_V_g_GND) =  " <<d_staticContributions[admsNodeID_g][admsProbeID_V_g_GND] << std::endl;
    Xyce::dout() << " dynamicContributions[admsNodeID_g] =  "
         <<dynamicContributions[admsNodeID_g] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_g].dx(admsProbeID_V_sf_GND) =  " <<d_dynamicContributions[admsNodeID_g][admsProbeID_V_sf_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_g].dx(admsProbeID_V_s_GND) =  " <<d_dynamicContributions[admsNodeID_g][admsProbeID_V_s_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_g].dx(admsProbeID_V_d_GND) =  " <<d_dynamicContributions[admsNodeID_g][admsProbeID_V_d_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_g].dx(admsProbeID_V_di_GND) =  " <<d_dynamicContributions[admsNodeID_g][admsProbeID_V_di_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_g].dx(admsProbeID_V_si_GND) =  " <<d_dynamicContributions[admsNodeID_g][admsProbeID_V_si_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_g].dx(admsProbeID_V_g_GND) =  " <<d_dynamicContributions[admsNodeID_g][admsProbeID_V_g_GND] << std::endl;
    Xyce::dout() << " staticContributions[admsNodeID_s] =  "
         <<staticContributions[admsNodeID_s] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_s].dx(admsProbeID_V_sf_GND) =  " <<d_staticContributions[admsNodeID_s][admsProbeID_V_sf_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_s].dx(admsProbeID_V_s_GND) =  " <<d_staticContributions[admsNodeID_s][admsProbeID_V_s_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_s].dx(admsProbeID_V_d_GND) =  " <<d_staticContributions[admsNodeID_s][admsProbeID_V_d_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_s].dx(admsProbeID_V_di_GND) =  " <<d_staticContributions[admsNodeID_s][admsProbeID_V_di_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_s].dx(admsProbeID_V_si_GND) =  " <<d_staticContributions[admsNodeID_s][admsProbeID_V_si_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_s].dx(admsProbeID_V_g_GND) =  " <<d_staticContributions[admsNodeID_s][admsProbeID_V_g_GND] << std::endl;
    Xyce::dout() << " dynamicContributions[admsNodeID_s] =  "
         <<dynamicContributions[admsNodeID_s] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_s].dx(admsProbeID_V_sf_GND) =  " <<d_dynamicContributions[admsNodeID_s][admsProbeID_V_sf_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_s].dx(admsProbeID_V_s_GND) =  " <<d_dynamicContributions[admsNodeID_s][admsProbeID_V_s_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_s].dx(admsProbeID_V_d_GND) =  " <<d_dynamicContributions[admsNodeID_s][admsProbeID_V_d_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_s].dx(admsProbeID_V_di_GND) =  " <<d_dynamicContributions[admsNodeID_s][admsProbeID_V_di_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_s].dx(admsProbeID_V_si_GND) =  " <<d_dynamicContributions[admsNodeID_s][admsProbeID_V_si_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_s].dx(admsProbeID_V_g_GND) =  " <<d_dynamicContributions[admsNodeID_s][admsProbeID_V_g_GND] << std::endl;
    Xyce::dout() << " staticContributions[admsNodeID_di] =  "
         <<staticContributions[admsNodeID_di] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_di].dx(admsProbeID_V_sf_GND) =  " <<d_staticContributions[admsNodeID_di][admsProbeID_V_sf_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_di].dx(admsProbeID_V_s_GND) =  " <<d_staticContributions[admsNodeID_di][admsProbeID_V_s_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_di].dx(admsProbeID_V_d_GND) =  " <<d_staticContributions[admsNodeID_di][admsProbeID_V_d_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_di].dx(admsProbeID_V_di_GND) =  " <<d_staticContributions[admsNodeID_di][admsProbeID_V_di_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_di].dx(admsProbeID_V_si_GND) =  " <<d_staticContributions[admsNodeID_di][admsProbeID_V_si_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_di].dx(admsProbeID_V_g_GND) =  " <<d_staticContributions[admsNodeID_di][admsProbeID_V_g_GND] << std::endl;
    Xyce::dout() << " dynamicContributions[admsNodeID_di] =  "
         <<dynamicContributions[admsNodeID_di] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_di].dx(admsProbeID_V_sf_GND) =  " <<d_dynamicContributions[admsNodeID_di][admsProbeID_V_sf_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_di].dx(admsProbeID_V_s_GND) =  " <<d_dynamicContributions[admsNodeID_di][admsProbeID_V_s_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_di].dx(admsProbeID_V_d_GND) =  " <<d_dynamicContributions[admsNodeID_di][admsProbeID_V_d_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_di].dx(admsProbeID_V_di_GND) =  " <<d_dynamicContributions[admsNodeID_di][admsProbeID_V_di_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_di].dx(admsProbeID_V_si_GND) =  " <<d_dynamicContributions[admsNodeID_di][admsProbeID_V_si_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_di].dx(admsProbeID_V_g_GND) =  " <<d_dynamicContributions[admsNodeID_di][admsProbeID_V_g_GND] << std::endl;
    Xyce::dout() << " staticContributions[admsNodeID_si] =  "
         <<staticContributions[admsNodeID_si] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_si].dx(admsProbeID_V_sf_GND) =  " <<d_staticContributions[admsNodeID_si][admsProbeID_V_sf_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_si].dx(admsProbeID_V_s_GND) =  " <<d_staticContributions[admsNodeID_si][admsProbeID_V_s_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_si].dx(admsProbeID_V_d_GND) =  " <<d_staticContributions[admsNodeID_si][admsProbeID_V_d_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_si].dx(admsProbeID_V_di_GND) =  " <<d_staticContributions[admsNodeID_si][admsProbeID_V_di_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_si].dx(admsProbeID_V_si_GND) =  " <<d_staticContributions[admsNodeID_si][admsProbeID_V_si_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_si].dx(admsProbeID_V_g_GND) =  " <<d_staticContributions[admsNodeID_si][admsProbeID_V_g_GND] << std::endl;
    Xyce::dout() << " dynamicContributions[admsNodeID_si] =  "
         <<dynamicContributions[admsNodeID_si] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_si].dx(admsProbeID_V_sf_GND) =  " <<d_dynamicContributions[admsNodeID_si][admsProbeID_V_sf_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_si].dx(admsProbeID_V_s_GND) =  " <<d_dynamicContributions[admsNodeID_si][admsProbeID_V_s_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_si].dx(admsProbeID_V_d_GND) =  " <<d_dynamicContributions[admsNodeID_si][admsProbeID_V_d_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_si].dx(admsProbeID_V_di_GND) =  " <<d_dynamicContributions[admsNodeID_si][admsProbeID_V_di_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_si].dx(admsProbeID_V_si_GND) =  " <<d_dynamicContributions[admsNodeID_si][admsProbeID_V_si_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_si].dx(admsProbeID_V_g_GND) =  " <<d_dynamicContributions[admsNodeID_si][admsProbeID_V_g_GND] << std::endl;
    Xyce::dout() << " staticContributions[admsNodeID_sf] =  "
         <<staticContributions[admsNodeID_sf] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_sf].dx(admsProbeID_V_sf_GND) =  " <<d_staticContributions[admsNodeID_sf][admsProbeID_V_sf_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_sf].dx(admsProbeID_V_s_GND) =  " <<d_staticContributions[admsNodeID_sf][admsProbeID_V_s_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_sf].dx(admsProbeID_V_d_GND) =  " <<d_staticContributions[admsNodeID_sf][admsProbeID_V_d_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_sf].dx(admsProbeID_V_di_GND) =  " <<d_staticContributions[admsNodeID_sf][admsProbeID_V_di_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_sf].dx(admsProbeID_V_si_GND) =  " <<d_staticContributions[admsNodeID_sf][admsProbeID_V_si_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsNodeID_sf].dx(admsProbeID_V_g_GND) =  " <<d_staticContributions[admsNodeID_sf][admsProbeID_V_g_GND] << std::endl;
    Xyce::dout() << " dynamicContributions[admsNodeID_sf] =  "
         <<dynamicContributions[admsNodeID_sf] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_sf].dx(admsProbeID_V_sf_GND) =  " <<d_dynamicContributions[admsNodeID_sf][admsProbeID_V_sf_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_sf].dx(admsProbeID_V_s_GND) =  " <<d_dynamicContributions[admsNodeID_sf][admsProbeID_V_s_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_sf].dx(admsProbeID_V_d_GND) =  " <<d_dynamicContributions[admsNodeID_sf][admsProbeID_V_d_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_sf].dx(admsProbeID_V_di_GND) =  " <<d_dynamicContributions[admsNodeID_sf][admsProbeID_V_di_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_sf].dx(admsProbeID_V_si_GND) =  " <<d_dynamicContributions[admsNodeID_sf][admsProbeID_V_si_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsNodeID_sf].dx(admsProbeID_V_g_GND) =  " <<d_dynamicContributions[admsNodeID_sf][admsProbeID_V_g_GND] << std::endl;
    Xyce::dout() << " staticContributions[admsBRA_ID_sf_GND] =  "
         <<staticContributions[admsBRA_ID_sf_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsBRA_ID_sf_GND].dx(admsProbeID_V_sf_GND) =  " <<d_staticContributions[admsBRA_ID_sf_GND][admsProbeID_V_sf_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsBRA_ID_sf_GND].dx(admsProbeID_V_s_GND) =  " <<d_staticContributions[admsBRA_ID_sf_GND][admsProbeID_V_s_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsBRA_ID_sf_GND].dx(admsProbeID_V_d_GND) =  " <<d_staticContributions[admsBRA_ID_sf_GND][admsProbeID_V_d_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsBRA_ID_sf_GND].dx(admsProbeID_V_di_GND) =  " <<d_staticContributions[admsBRA_ID_sf_GND][admsProbeID_V_di_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsBRA_ID_sf_GND].dx(admsProbeID_V_si_GND) =  " <<d_staticContributions[admsBRA_ID_sf_GND][admsProbeID_V_si_GND] << std::endl;
      Xyce::dout() << "    staticContributions[admsBRA_ID_sf_GND].dx(admsProbeID_V_g_GND) =  " <<d_staticContributions[admsBRA_ID_sf_GND][admsProbeID_V_g_GND] << std::endl;
    Xyce::dout() << " dynamicContributions[admsBRA_ID_sf_GND] =  "
         <<dynamicContributions[admsBRA_ID_sf_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsBRA_ID_sf_GND].dx(admsProbeID_V_sf_GND) =  " <<d_dynamicContributions[admsBRA_ID_sf_GND][admsProbeID_V_sf_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsBRA_ID_sf_GND].dx(admsProbeID_V_s_GND) =  " <<d_dynamicContributions[admsBRA_ID_sf_GND][admsProbeID_V_s_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsBRA_ID_sf_GND].dx(admsProbeID_V_d_GND) =  " <<d_dynamicContributions[admsBRA_ID_sf_GND][admsProbeID_V_d_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsBRA_ID_sf_GND].dx(admsProbeID_V_di_GND) =  " <<d_dynamicContributions[admsBRA_ID_sf_GND][admsProbeID_V_di_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsBRA_ID_sf_GND].dx(admsProbeID_V_si_GND) =  " <<d_dynamicContributions[admsBRA_ID_sf_GND][admsProbeID_V_si_GND] << std::endl;
      Xyce::dout() << "    dynamicContributions[admsBRA_ID_sf_GND].dx(admsProbeID_V_g_GND) =  " <<d_dynamicContributions[admsBRA_ID_sf_GND][admsProbeID_V_g_GND] << std::endl;

    if (!origFlag)
      Xyce::dout() << "This step was limited by this device." << std::endl;
  }


  if (loadLeadCurrent)
  {
    // If needed, we must now copy all the data from staticContributions
    // and dynamicContributionsinto the lead current F vector
    // Must make sure all collapsed node contributions get summed into the
    // external nodes properly.
    for ( int unmappedNode=0; unmappedNode < 3 ; unmappedNode++)
    {
      leadCurrentF[unmappedNode] = 0.0;
      leadCurrentQ[unmappedNode] = 0.0;
    }
    for ( int unmappedNode=0; unmappedNode < 6; unmappedNode++)
    {
      if (nodeMap[unmappedNode] < 3 && nodeMap[unmappedNode] != -1 )
      {
        leadCurrentF[nodeMap[unmappedNode]] += staticContributions[unmappedNode];
        leadCurrentQ[nodeMap[unmappedNode]] += dynamicContributions[unmappedNode];
      }
    }
  }
  return true;
}


//-----------------------------------------------------------------------------
// Function      : Instance::loadDAEdFdx
// Purpose       :
// Special Notes : Load the dFdx ("static jacobian") matrix
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
bool Instance::loadDAEdFdx()
{
  bool bsuccess = true;
  Linear::Matrix & dFdx = *(extData.dFdxMatrixPtr);

#ifndef Xyce_NONPOINTER_MATRIX_LOAD
  (*f_di_Equ_si_Node_Ptr) +=  +d_staticContributions[admsNodeID_di][admsProbeID_V_si_GND];
  (*f_si_Equ_si_Node_Ptr) +=  +d_staticContributions[admsNodeID_si][admsProbeID_V_si_GND];
  (*f_di_Equ_di_Node_Ptr) +=  +d_staticContributions[admsNodeID_di][admsProbeID_V_di_GND];
  (*f_si_Equ_di_Node_Ptr) +=  +d_staticContributions[admsNodeID_si][admsProbeID_V_di_GND];
  (*f_di_Equ_sf_Node_Ptr) +=  +d_staticContributions[admsNodeID_di][admsProbeID_V_sf_GND];
  (*f_si_Equ_sf_Node_Ptr) +=  +d_staticContributions[admsNodeID_si][admsProbeID_V_sf_GND];
  (*f_d_Equ_di_Node_Ptr) +=  +d_staticContributions[admsNodeID_d][admsProbeID_V_di_GND];
  (*f_d_Equ_d_Node_Ptr) +=  +d_staticContributions[admsNodeID_d][admsProbeID_V_d_GND];
  (*f_di_Equ_d_Node_Ptr) +=  +d_staticContributions[admsNodeID_di][admsProbeID_V_d_GND];
  (*f_si_Equ_s_Node_Ptr) +=  +d_staticContributions[admsNodeID_si][admsProbeID_V_s_GND];
  (*f_s_Equ_s_Node_Ptr) +=  +d_staticContributions[admsNodeID_s][admsProbeID_V_s_GND];
  (*f_s_Equ_si_Node_Ptr) +=  +d_staticContributions[admsNodeID_s][admsProbeID_V_si_GND];
  (*f_sf_Equ_BRA_sf_GND_Var_Ptr) += d_staticContributions[admsNodeID_sf][admsProbeID_I_sf_GND];
    // there also need to be extra loads for branch sf,GND
    // Load for branch sf,GND equ var sf
     // depends on probe V(sf,GND)
  (*f_BRA_sf_GND_Equ_sf_Node_Ptr) +=  +d_staticContributions[admsBRA_ID_sf_GND][admsProbeID_V_sf_GND] -1;
    // Load for branch sf,GND equ var si
     // depends on probe V(si,GND)
  (*f_BRA_sf_GND_Equ_si_Node_Ptr) +=  +d_staticContributions[admsBRA_ID_sf_GND][admsProbeID_V_si_GND];
    // Load for branch sf,GND equ var g
     // depends on probe V(g,GND)
  (*f_BRA_sf_GND_Equ_g_Node_Ptr) +=  +d_staticContributions[admsBRA_ID_sf_GND][admsProbeID_V_g_GND];
    // Load for branch sf,GND equ var di
     // depends on probe V(di,GND)
  (*f_BRA_sf_GND_Equ_di_Node_Ptr) +=  +d_staticContributions[admsBRA_ID_sf_GND][admsProbeID_V_di_GND];

#else
  //use the offsets instead of pointers
  dFdx[li_di][A_di_Equ_si_NodeOffset] +=  +d_staticContributions[admsNodeID_di][admsProbeID_V_si_GND];
  dFdx[li_si][A_si_Equ_si_NodeOffset] +=  +d_staticContributions[admsNodeID_si][admsProbeID_V_si_GND];
  dFdx[li_di][A_di_Equ_di_NodeOffset] +=  +d_staticContributions[admsNodeID_di][admsProbeID_V_di_GND];
  dFdx[li_si][A_si_Equ_di_NodeOffset] +=  +d_staticContributions[admsNodeID_si][admsProbeID_V_di_GND];
  dFdx[li_di][A_di_Equ_sf_NodeOffset] +=  +d_staticContributions[admsNodeID_di][admsProbeID_V_sf_GND];
  dFdx[li_si][A_si_Equ_sf_NodeOffset] +=  +d_staticContributions[admsNodeID_si][admsProbeID_V_sf_GND];
  dFdx[li_d][A_d_Equ_di_NodeOffset] +=  +d_staticContributions[admsNodeID_d][admsProbeID_V_di_GND];
  dFdx[li_d][A_d_Equ_d_NodeOffset] +=  +d_staticContributions[admsNodeID_d][admsProbeID_V_d_GND];
  dFdx[li_di][A_di_Equ_d_NodeOffset] +=  +d_staticContributions[admsNodeID_di][admsProbeID_V_d_GND];
  dFdx[li_si][A_si_Equ_s_NodeOffset] +=  +d_staticContributions[admsNodeID_si][admsProbeID_V_s_GND];
  dFdx[li_s][A_s_Equ_s_NodeOffset] +=  +d_staticContributions[admsNodeID_s][admsProbeID_V_s_GND];
  dFdx[li_s][A_s_Equ_si_NodeOffset] +=  +d_staticContributions[admsNodeID_s][admsProbeID_V_si_GND];
  dFdx[li_sf][A_sf_Equ_BRA_sf_GND_Var_Offset] += d_staticContributions[admsNodeID_sf][admsProbeID_I_sf_GND];
    // there also need to be extra loads for branch sf,GND
    // Load for branch sf,GND equ var sf
     // depends on probe V(sf,GND)
  dFdx[li_BRA_sf_GND][A_BRA_sf_GND_Equ_sf_Node_Offset] +=  +d_staticContributions[admsBRA_ID_sf_GND][admsProbeID_V_sf_GND] -1;
    // Load for branch sf,GND equ var si
     // depends on probe V(si,GND)
  dFdx[li_BRA_sf_GND][A_BRA_sf_GND_Equ_si_Node_Offset] +=  +d_staticContributions[admsBRA_ID_sf_GND][admsProbeID_V_si_GND];
    // Load for branch sf,GND equ var g
     // depends on probe V(g,GND)
  dFdx[li_BRA_sf_GND][A_BRA_sf_GND_Equ_g_Node_Offset] +=  +d_staticContributions[admsBRA_ID_sf_GND][admsProbeID_V_g_GND];
    // Load for branch sf,GND equ var di
     // depends on probe V(di,GND)
  dFdx[li_BRA_sf_GND][A_BRA_sf_GND_Equ_di_Node_Offset] +=  +d_staticContributions[admsBRA_ID_sf_GND][admsProbeID_V_di_GND];

#endif

  return bsuccess;
}


//-----------------------------------------------------------------------------
// Function      : Instance::loadDAEdQdx
// Purpose       :
// Special Notes : Load the dQdx ("dynamic jacobian") matrix
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
bool Instance::loadDAEdQdx()
{
  bool bsuccess = true;
  Linear::Matrix & dQdx = *(extData.dQdxMatrixPtr);

#ifndef Xyce_NONPOINTER_MATRIX_LOAD
  (*q_sf_Equ_BRA_sf_GND_Var_Ptr) += d_dynamicContributions[admsNodeID_sf][admsProbeID_I_sf_GND];
    // there also need to be extra loads for branch sf,GND
    // Load for branch sf,GND equ var sf
    // Load for branch sf,GND equ var si
    // Load for branch sf,GND equ var g
    // Load for branch sf,GND equ var di

#else
  //use the offsets instead of pointers
  dQdx[li_sf][A_sf_Equ_BRA_sf_GND_Var_Offset] += d_dynamicContributions[admsNodeID_sf][admsProbeID_I_sf_GND];
    // there also need to be extra loads for branch sf,GND
    // Load for branch sf,GND equ var sf
    // Load for branch sf,GND equ var si
    // Load for branch sf,GND equ var g
    // Load for branch sf,GND equ var di


#endif
  return bsuccess;
}




//-----------------------------------------------------------------------------
// Function      : Instance::updateTemperature
// Purpose       : Set temperature and update any parameters that depend on it
// Special Notes : In Xyce ADMS, we'll simply copy the temperature, which is
//                 in Kelvin, to our "admsTemperature" variable, which needs
//                 to be in Celsius.
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
bool Instance::updateTemperature(const double & temperatureTemp)
{

  admsTemperature = temperatureTemp;
  adms_vt_nom = adms_vt(temperatureTemp);

  return true;
}

// Class Model
//-----------------------------------------------------------------------------
// Function      : Model::processParams
// Purpose       :
// Special Notes :
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
bool Model::processParams()
{

  // Set any non-constant parameter defaults:
  // Set any parameters that were not given and whose defaults depend on other
  // parameters:

// set internal model type based on model card type
if (getType() == "pmos" || getType() == "PMOS")
    type = -1;



  // Now we need to check that any parameters are within their ranges as
  // specified in the verilog:

//    Parameter type : [ (-1), 1 ]] 0, 0 [
  if ( (!((type >=(-1) && type <=1 )) || (type >0 && type <0 )) )
  {
    UserWarning(*this) << "ADMSmvs_2_0_0_etsoi: Parameter type value " << type << " out of range [ (-1), 1 ] or  ] 0, 0 [";
  }

//    Parameter W : ] 0,  (+inf) [
  if ( (!((W >0))) )
  {
    UserWarning(*this) << "ADMSmvs_2_0_0_etsoi: Parameter W value " << W << " out of range ] 0,  (+inf) [";
  }

//    Parameter Lgdr : ] 0,  (+inf) [
  if ( (!((Lgdr >0))) )
  {
    UserWarning(*this) << "ADMSmvs_2_0_0_etsoi: Parameter Lgdr value " << Lgdr << " out of range ] 0,  (+inf) [";
  }

//    Parameter dLg : [ 0,  (+inf) [
  if ( (!((dLg >=0))) )
  {
    UserWarning(*this) << "ADMSmvs_2_0_0_etsoi: Parameter dLg value " << dLg << " out of range [ 0,  (+inf) [";
  }

//    Parameter Cins : ] 0,  (+inf) [
  if ( (!((Cins >0))) )
  {
    UserWarning(*this) << "ADMSmvs_2_0_0_etsoi: Parameter Cins value " << Cins << " out of range ] 0,  (+inf) [";
  }

//    Parameter Tjun : ] 0,  (+inf) [
  if ( (!((Tjun >0))) )
  {
    UserWarning(*this) << "ADMSmvs_2_0_0_etsoi: Parameter Tjun value " << Tjun << " out of range ] 0,  (+inf) [";
  }

//    Parameter energy_diff_volt :  ] (-inf)  (+inf) [

//    Parameter delta : [ 0,  (+inf) [
  if ( (!((delta >=0))) )
  {
    UserWarning(*this) << "ADMSmvs_2_0_0_etsoi: Parameter delta value " << delta << " out of range [ 0,  (+inf) [";
  }

//    Parameter n0 : [ 1.0,  (+inf) [
  if ( (!((n0 >=1.0))) )
  {
    UserWarning(*this) << "ADMSmvs_2_0_0_etsoi: Parameter n0 value " << n0 << " out of range [ 1.0,  (+inf) [";
  }

//    Parameter Rs0 : ] 0,  (+inf) [
  if ( (!((Rs0 >0))) )
  {
    UserWarning(*this) << "ADMSmvs_2_0_0_etsoi: Parameter Rs0 value " << Rs0 << " out of range ] 0,  (+inf) [";
  }

//    Parameter mt : ] 0, 1 ]
  if ( (!((mt >0 && mt <=1 ))) )
  {
    UserWarning(*this) << "ADMSmvs_2_0_0_etsoi: Parameter mt value " << mt << " out of range ] 0, 1 ]";
  }

//    Parameter ml : ] 0, 1 ]
  if ( (!((ml >0 && ml <=1 ))) )
  {
    UserWarning(*this) << "ADMSmvs_2_0_0_etsoi: Parameter ml value " << ml << " out of range ] 0, 1 ]";
  }

//    Parameter nu : [ 0, 1 ]
  if ( (!((nu >=0 && nu <=1 ))) )
  {
    UserWarning(*this) << "ADMSmvs_2_0_0_etsoi: Parameter nu value " << nu << " out of range [ 0, 1 ]";
  }

//    Parameter mu_eff : ] 0,  (+inf) [
  if ( (!((mu_eff >0))) )
  {
    UserWarning(*this) << "ADMSmvs_2_0_0_etsoi: Parameter mu_eff value " << mu_eff << " out of range ] 0,  (+inf) [";
  }

//    Parameter ksee : ] 0,  (+inf) [
  if ( (!((ksee >0))) )
  {
    UserWarning(*this) << "ADMSmvs_2_0_0_etsoi: Parameter ksee value " << ksee << " out of range ] 0,  (+inf) [";
  }

//    Parameter B : ] 0,  (+inf) [
  if ( (!((B >0))) )
  {
    UserWarning(*this) << "ADMSmvs_2_0_0_etsoi: Parameter B value " << B << " out of range ] 0,  (+inf) [";
  }

//    Parameter dqm0 : ] 0,  (+inf) [
  if ( (!((dqm0 >0))) )
  {
    UserWarning(*this) << "ADMSmvs_2_0_0_etsoi: Parameter dqm0 value " << dqm0 << " out of range ] 0,  (+inf) [";
  }

//    Parameter eps : ] 0,  (+inf) [
  if ( (!((eps >0))) )
  {
    UserWarning(*this) << "ADMSmvs_2_0_0_etsoi: Parameter eps value " << eps << " out of range ] 0,  (+inf) [";
  }

//    Parameter theta : ] 0,  (+inf) [
  if ( (!((theta >0))) )
  {
    UserWarning(*this) << "ADMSmvs_2_0_0_etsoi: Parameter theta value " << theta << " out of range ] 0,  (+inf) [";
  }

//    Parameter beta : [ 1,  (+inf) [
  if ( (!((beta >=1))) )
  {
    UserWarning(*this) << "ADMSmvs_2_0_0_etsoi: Parameter beta value " << beta << " out of range [ 1,  (+inf) [";
  }

//    Parameter nd : [ 0,  (+inf) [
  if ( (!((nd >=0))) )
  {
    UserWarning(*this) << "ADMSmvs_2_0_0_etsoi: Parameter nd value " << nd << " out of range [ 0,  (+inf) [";
  }

  // and of course, this routine is where we should put the initial_model
  // stuff


  return true;
}
//----------------------------------------------------------------------------
// Function      : Model::processInstanceParams
// Purpose       :
// Special Notes :
// Scope         : public
// Creator       :
// Creation Date :
//----------------------------------------------------------------------------
bool Model::processInstanceParams()
{

  std::vector<Instance*>::iterator iter;
  std::vector<Instance*>::iterator first = instanceContainer.begin();
  std::vector<Instance*>::iterator last  = instanceContainer.end();

  for (iter=first; iter!=last; ++iter)
  {
    (*iter)->processParams();
  }

  return true;
}

//-----------------------------------------------------------------------------
// Function      : Model::Model
// Purpose       : model block constructor
// Special Notes :
// Scope         : public
// Creator       :
// Creation Date :
//-----------------------------------------------------------------------------
Model::Model(
  const Configuration & configuration,
  const ModelBlock &    model_block,
  const FactoryBlock &  factory_block)
  : DeviceModel(model_block, configuration.getModelParameters(), factory_block),
    version(2.00),
    type(1),
    W(1.0e-6),
    Lgdr(80.0e-9),
    dLg(10.5e-9),
    Cins(3.17e-2),
    Tjun(300.0),
    energy_diff_volt(0.153),
    delta(0.120),
    n0(1.35),
    Rs0(160.0e-6),
    mt(0.19),
    ml(0.89),
    nu(0.7),
    mu_eff(1.0),
    ksee(0.1),
    B(6.8e-9),
    dqm0(4.6e-9),
    eps(13.6),
    theta(2.5),
    beta(1.55),
    nd(0.0)
{
  // Set params to constant default values (from parTable):
  setDefaultParams();

  // Set params according to .model line and constant defaults from metadata:
  setModParams(model_block.params);

  if (!given("XYCEADMSMODTEMP"))
    admsModTemp=getDeviceOptions().temp.getImmutableValue<double>();

  // Calculate any parameters specified as expressions:

  updateDependentParameters();

  // calculate dependent (ie computed) params and check for errors:
  processParams();
}

//-----------------------------------------------------------------------------
// Function      : Model::~Model
// Purpose       : destructor
// Special Notes :
// Scope         : public
// Creator       :
// Creation Date :
//-----------------------------------------------------------------------------
Model::~Model()
{
  std::vector<Instance*>::iterator iterI;
  std::vector<Instance*>::iterator firstI = instanceContainer.begin ();
  std::vector<Instance*>::iterator lastI  = instanceContainer.end ();

  // loop over instances:
  for (iterI = firstI; iterI != lastI; ++iterI)
  {
    delete (*iterI);
  }
}

//-----------------------------------------------------------------------------
// Function      : Model::printOutInstances
// Purpose       : debugging tool.
// Special Notes :
// Scope         : public
// Creator       :
// Creation Date :
//-----------------------------------------------------------------------------
std::ostream &Model::printOutInstances(std::ostream &os) const
{
  std::vector<Instance*>::const_iterator iter;
  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
  std::vector<Instance*>::const_iterator last  = instanceContainer.end();

  int i;
  os << std::endl;
  os << "    name     model name  Parameters" << std::endl;
  for (i=0, iter=first; iter!=last; ++iter, ++i)
  {
    os << "  " << i << ": " << (*iter)->getName() << "      ";
    os << getName();

    os << std::endl;
    os << std::endl;
  }

  os << std::endl;

  return os;
}

//-----------------------------------------------------------------------------
// Function      : Model::forEachInstance
// Purpose       :
// Special Notes :
// Scope         : public
// Creator       : David Baur
// Creation Date : 2/4/2014
//-----------------------------------------------------------------------------
/// Apply a device instance "op" to all instances associated with this
/// model
///
/// @param[in] op Operator to apply to all instances.
///
///
void Model::forEachInstance(DeviceInstanceOp &op) const
{
  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
    op(*it);
}

Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
{
  return new DeviceMaster<Traits>(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
}

void
registerDevice(const DeviceCountMap& deviceMap, const std::set<int>& levelSet)
{
if (deviceMap.empty() ||
((deviceMap.find("M") != deviceMap.end() && (levelSet.find(2000)!=levelSet.end()))))
{
MOSFET1::registerDevice();
  Config<Traits>::addConfiguration()
    .registerDevice("m", 2000)
    .registerModelType("nmos", 2000)
    .registerModelType("pmos", 2000);
}
}


#ifdef Xyce_ADMS_SENSITIVITIES
//-----------------------------------------------------------------------------
// Function      : evaluateInitialInstance
// Purpose       : Evaluate the statements in the initial_instance block
// Special Notes : specific for sensitivity use
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
void evaluateInitialInstance(
instanceSensStruct & instanceStruct,
modelSensStruct & modelStruct,
 double admsTemperature, double adms_vt_nom, double ADMSgmin_arg, const Instance & theInstance)
{
}



//-----------------------------------------------------------------------------
// Function      : evaluateInitialModel
// Purpose       : Evaluate the statements in the initial_model block
// Special Notes : specific for sensitivity use
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
void evaluateInitialModel(
modelSensStruct & modelStruct,
 double admsTemperature, double ADMSgmin_arg, const Instance & theInstance)
{
}



//-----------------------------------------------------------------------------
// Function      : evaluateModelEquations
// Purpose       : Evaluate the main module block.  Similar to
//                 updateIntermediateVars, but takes all instance and model
//                 parameters and variables as arguments instead of using
//                 the ones stored in the objects.
// Special Notes : specific for sensitivity use
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
void evaluateModelEquations(
std::vector <double> & probeVars,
// probe constants
const int admsProbeID_V_sf_GND,
const int admsProbeID_V_s_GND,
const int admsProbeID_V_d_GND,
const int admsProbeID_V_di_GND,
const int admsProbeID_V_si_GND,
const int admsProbeID_V_g_GND,
const int admsProbeID_I_sf_GND,
// node constants
const int admsNodeID_d,
const int admsNodeID_g,
const int admsNodeID_s,
const int admsNodeID_di,
const int admsNodeID_si,
const int admsNodeID_sf,
const int admsBRA_ID_sf_GND,
instanceSensStruct & instanceStruct,
modelSensStruct & modelStruct,
// basic variables
 double admsTemperature, double adms_vt_nom, double ADMSgmin_arg, std::vector <double> & d_staticContributions_dX, std::vector <double> & d_dynamicContributions_dX, const Instance & theInstance)
{

  // Local variables
  double Id=0.0;
double d_Id_dX=0.0;
  double vx0=0.0;
double d_vx0_dX=0.0;
  double Fsat=0.0;
double d_Fsat_dX=0.0;
  double Vdsatbeta=0.0;
double d_Vdsatbeta_dX=0.0;
  double Vdsat=0.0;
double d_Vdsat_dX=0.0;
  double f1=0.0;
double d_f1_dX=0.0;
  double n=0.0;
double d_n_dX=0.0;
  double Cgc=0.0;
double d_Cgc_dX=0.0;
  double Cstern=0.0;
double d_Cstern_dX=0.0;
  double xav=0.0;
double d_xav_dX=0.0;
  double QB=0.0;
double d_QB_dX=0.0;
  double Qx0=0.0;
double d_Qx0_dX=0.0;
  double Tx=0.0;
double d_Tx_dX=0.0;
  double Lcrit=0.0;
double d_Lcrit_dX=0.0;
  double Lcrit_sat=0.0;
double d_Lcrit_sat_dX=0.0;
  double Lcrit_lin=0.0;
double d_Lcrit_lin_dX=0.0;
  double f2=0.0;
double d_f2_dX=0.0;
  double Vdsatbeta2=0.0;
double d_Vdsatbeta2_dX=0.0;
  double Vdsat2=0.0;
double d_Vdsat2_dX=0.0;
  double Fd=0.0;
double d_Fd_dX=0.0;
  double Fs=0.0;
double d_Fs_dX=0.0;
  double Fd_delta4=0.0;
double d_Fd_delta4_dX=0.0;
  double Fd_delta2=0.0;
double d_Fd_delta2_dX=0.0;
  double Fs_delta4=0.0;
double d_Fs_delta4_dX=0.0;
  double Fs_delta2=0.0;
double d_Fs_delta2_dX=0.0;
  double lnoneplusEd=0.0;
double d_lnoneplusEd_dX=0.0;
  double lnoneplusEs=0.0;
double d_lnoneplusEs_dX=0.0;
  double Ed_delta2=0.0;
double d_Ed_delta2_dX=0.0;
  double Es_delta2=0.0;
double d_Es_delta2_dX=0.0;
  double Rd=0.0;
double d_Rd_dX=0.0;
  double Rs=0.0;
double d_Rs_dX=0.0;
  double Leff=0.0;
double d_Leff_dX=0.0;
  double N2D=0.0;
double d_N2D_dX=0.0;
  double lambda=0.0;
double d_lambda_dX=0.0;
  double vT=0.0;
double d_vT_dX=0.0;
  double vT_delta4_int=0.0;
double d_vT_delta4_int_dX=0.0;
  double mC_delta4=0.0;
double d_mC_delta4_dX=0.0;
  double mD_delta4=0.0;
double d_mD_delta4_dX=0.0;
  double vT_delta2_int=0.0;
double d_vT_delta2_int_dX=0.0;
  double mC_delta2=0.0;
double d_mC_delta2_dX=0.0;
  double mD_delta2=0.0;
double d_mD_delta2_dX=0.0;
  double hbar=0.0;
  double kT=0.0;
double d_kT_dX=0.0;
  double phit=0.0;
double d_phit_dX=0.0;
  double dir=0.0;
  double Vgsi=0.0;
double d_Vgsi_dX=0.0;
  double Vdsi=0.0;
double d_Vdsi_dX=0.0;
  double Vgs=0.0;
double d_Vgs_dX=0.0;
  double Vds=0.0;
double d_Vds_dX=0.0;
  double Vgdraw=0.0;
double d_Vgdraw_dX=0.0;
  double Vgsraw=0.0;
double d_Vgsraw_dX=0.0;


  // -- code converted from analog/code block
d_Vgsraw_dX = 0.0;
Vgsraw = (modelStruct.modelPar_type*((probeVars[admsProbeID_V_g_GND])-(probeVars[admsProbeID_V_si_GND])));
d_Vgdraw_dX = 0.0;
Vgdraw = (modelStruct.modelPar_type*((probeVars[admsProbeID_V_g_GND])-(probeVars[admsProbeID_V_di_GND])));
if ((Vgsraw>=Vgdraw))
{
d_Vds_dX = 0.0;
Vds = (modelStruct.modelPar_type*((probeVars[admsProbeID_V_d_GND])-(probeVars[admsProbeID_V_s_GND])));
d_Vgs_dX = 0.0;
Vgs = (modelStruct.modelPar_type*((probeVars[admsProbeID_V_g_GND])-(probeVars[admsProbeID_V_s_GND])));
d_Vdsi_dX = 0.0;
Vdsi = (modelStruct.modelPar_type*((probeVars[admsProbeID_V_di_GND])-(probeVars[admsProbeID_V_si_GND])));
d_Vgsi_dX = d_Vgsraw_dX;
Vgsi = Vgsraw;
dir = 1;
}
else
{
d_Vds_dX = 0.0;
Vds = (modelStruct.modelPar_type*((probeVars[admsProbeID_V_s_GND])-(probeVars[admsProbeID_V_d_GND])));
d_Vgs_dX = 0.0;
Vgs = (modelStruct.modelPar_type*((probeVars[admsProbeID_V_g_GND])-(probeVars[admsProbeID_V_d_GND])));
d_Vdsi_dX = 0.0;
Vdsi = (modelStruct.modelPar_type*((probeVars[admsProbeID_V_si_GND])-(probeVars[admsProbeID_V_di_GND])));
d_Vgsi_dX = d_Vgdraw_dX;
Vgsi = Vgdraw;
dir = (-1);
}
d_phit_dX = (1.3806503e-23*modelStruct.d_modelPar_Tjun_dX/1.6021766208e-19);
phit = ((1.3806503e-23*modelStruct.modelPar_Tjun)/1.6021766208e-19);
d_kT_dX = 1.3806503e-23*modelStruct.d_modelPar_Tjun_dX;
kT = (1.3806503e-23*modelStruct.modelPar_Tjun);
hbar = (6.62607004081e-34/(2.0*3.14159265358979323846));
d_mD_delta2_dX = 2.0*modelStruct.d_modelPar_mt_dX*9.10938215e-31;
mD_delta2 = ((2.0*modelStruct.modelPar_mt)*9.10938215e-31);
d_mC_delta2_dX = 4.0*modelStruct.d_modelPar_mt_dX*9.10938215e-31;
mC_delta2 = ((4.0*modelStruct.modelPar_mt)*9.10938215e-31);
{
double value_sqrt_0 = sqrt(((((2.0*kT)/3.14159265358979323846)*mC_delta2)/(mD_delta2*mD_delta2)));
double  deriv_sqrt_0_d0 = (0.5/value_sqrt_0);
d_vT_delta2_int_dX = deriv_sqrt_0_d0*((((mD_delta2*mD_delta2)*(((2.0*kT)/3.14159265358979323846)*d_mC_delta2_dX+(2.0*d_kT_dX/3.14159265358979323846)*mC_delta2)-(((2.0*kT)/3.14159265358979323846)*mC_delta2)*(mD_delta2*d_mD_delta2_dX+d_mD_delta2_dX*mD_delta2))/(mD_delta2*mD_delta2)/(mD_delta2*mD_delta2)));
vT_delta2_int = value_sqrt_0;
}
{
double value_sqrt_0 = sqrt((modelStruct.modelPar_mt*modelStruct.modelPar_ml));
double  deriv_sqrt_0_d0 = (0.5/value_sqrt_0);
d_mD_delta4_dX = 4.0*deriv_sqrt_0_d0*((modelStruct.modelPar_mt*modelStruct.d_modelPar_ml_dX+modelStruct.d_modelPar_mt_dX*modelStruct.modelPar_ml))*9.10938215e-31;
mD_delta4 = ((4.0*value_sqrt_0)*9.10938215e-31);
}
{
double value_sqrt_0 = sqrt(modelStruct.modelPar_mt);
double value_sqrt_1 = sqrt(modelStruct.modelPar_ml);
double value_sqrt_2 = sqrt(modelStruct.modelPar_mt);
double value_sqrt_3 = sqrt(modelStruct.modelPar_ml);
double  deriv_sqrt_0_d0 = (0.5/value_sqrt_0);
double  deriv_sqrt_1_d0 = (0.5/value_sqrt_1);
double  deriv_sqrt_2_d0 = (0.5/value_sqrt_2);
double  deriv_sqrt_3_d0 = (0.5/value_sqrt_3);
d_mC_delta4_dX = ((4.0*(value_sqrt_0+value_sqrt_1))*(deriv_sqrt_2_d0*(modelStruct.d_modelPar_mt_dX)+deriv_sqrt_3_d0*(modelStruct.d_modelPar_ml_dX))+4.0*(deriv_sqrt_0_d0*(modelStruct.d_modelPar_mt_dX)+deriv_sqrt_1_d0*(modelStruct.d_modelPar_ml_dX))*(value_sqrt_2+value_sqrt_3))*9.10938215e-31;
mC_delta4 = (((4.0*(value_sqrt_0+value_sqrt_1))*(value_sqrt_2+value_sqrt_3))*9.10938215e-31);
}
{
double value_sqrt_0 = sqrt(((((2.0*kT)/3.14159265358979323846)*mC_delta4)/(mD_delta4*mD_delta4)));
double  deriv_sqrt_0_d0 = (0.5/value_sqrt_0);
d_vT_delta4_int_dX = deriv_sqrt_0_d0*((((mD_delta4*mD_delta4)*(((2.0*kT)/3.14159265358979323846)*d_mC_delta4_dX+(2.0*d_kT_dX/3.14159265358979323846)*mC_delta4)-(((2.0*kT)/3.14159265358979323846)*mC_delta4)*(mD_delta4*d_mD_delta4_dX+d_mD_delta4_dX*mD_delta4))/(mD_delta4*mD_delta4)/(mD_delta4*mD_delta4)));
vT_delta4_int = value_sqrt_0;
}
d_vT_dX = ((modelStruct.modelPar_nu*d_vT_delta2_int_dX+modelStruct.d_modelPar_nu_dX*vT_delta2_int)+((1.0-modelStruct.modelPar_nu)*d_vT_delta4_int_dX+(-modelStruct.d_modelPar_nu_dX)*vT_delta4_int));
vT = ((modelStruct.modelPar_nu*vT_delta2_int)+((1.0-modelStruct.modelPar_nu)*vT_delta4_int));
d_lambda_dX = ((vT*((2.0*phit)*modelStruct.d_modelPar_mu_eff_dX+2.0*d_phit_dX*modelStruct.modelPar_mu_eff)-((2.0*phit)*modelStruct.modelPar_mu_eff)*d_vT_dX)/vT/vT);
lambda = (((2.0*phit)*modelStruct.modelPar_mu_eff)/vT);
d_N2D_dX = ((mD_delta2/((3.14159265358979323846*hbar)*hbar))*d_kT_dX+(d_mD_delta2_dX/((3.14159265358979323846*hbar)*hbar))*kT);
N2D = ((mD_delta2/((3.14159265358979323846*hbar)*hbar))*kT);
d_Leff_dX = (modelStruct.d_modelPar_Lgdr_dX-modelStruct.d_modelPar_dLg_dX);
Leff = (modelStruct.modelPar_Lgdr-modelStruct.modelPar_dLg);
d_Rs_dX = ((modelStruct.modelPar_W*modelStruct.d_modelPar_Rs0_dX-modelStruct.modelPar_Rs0*modelStruct.d_modelPar_W_dX)/modelStruct.modelPar_W/modelStruct.modelPar_W);
Rs = (modelStruct.modelPar_Rs0/modelStruct.modelPar_W);
d_Rd_dX = d_Rs_dX;
Rd = Rs;
d_Es_delta2_dX = ((phit*modelStruct.d_modelPar_energy_diff_volt_dX-(modelStruct.modelPar_energy_diff_volt+(probeVars[admsProbeID_V_sf_GND]))*d_phit_dX)/phit/phit);
Es_delta2 = ((modelStruct.modelPar_energy_diff_volt+(probeVars[admsProbeID_V_sf_GND]))/phit);
d_Ed_delta2_dX = ((phit*(modelStruct.d_modelPar_energy_diff_volt_dX-d_Vdsi_dX)-((modelStruct.modelPar_energy_diff_volt+(probeVars[admsProbeID_V_sf_GND]))-Vdsi)*d_phit_dX)/phit/phit);
Ed_delta2 = (((modelStruct.modelPar_energy_diff_volt+(probeVars[admsProbeID_V_sf_GND]))-Vdsi)/phit);
if ((Es_delta2<=40))
{
{
double value_exp_0 = exp(Es_delta2);
double value_log_1 = log((1.0+value_exp_0));
double  deriv_exp_0_d0 = value_exp_0;
double  deriv_log_1_d0 = (1.0/(1.0+value_exp_0));
d_lnoneplusEs_dX = deriv_log_1_d0*(deriv_exp_0_d0*(d_Es_delta2_dX));
lnoneplusEs = value_log_1;
}
}
else
{
d_lnoneplusEs_dX = d_Es_delta2_dX;
lnoneplusEs = Es_delta2;
}
if ((Ed_delta2<=40))
{
{
double value_exp_0 = exp(Ed_delta2);
double value_log_1 = log((1.0+value_exp_0));
double  deriv_exp_0_d0 = value_exp_0;
double  deriv_log_1_d0 = (1.0/(1.0+value_exp_0));
d_lnoneplusEd_dX = deriv_log_1_d0*(deriv_exp_0_d0*(d_Ed_delta2_dX));
lnoneplusEd = value_log_1;
}
}
else
{
d_lnoneplusEd_dX = d_Ed_delta2_dX;
lnoneplusEd = Ed_delta2;
}
d_Fs_delta2_dX = d_lnoneplusEs_dX;
Fs_delta2 = lnoneplusEs;
d_Fs_delta4_dX = ((modelStruct.modelPar_nu*(Fs_delta2*(-modelStruct.d_modelPar_nu_dX)+d_Fs_delta2_dX*(1.0-modelStruct.modelPar_nu))-(Fs_delta2*(1.0-modelStruct.modelPar_nu))*modelStruct.d_modelPar_nu_dX)/modelStruct.modelPar_nu/modelStruct.modelPar_nu);
Fs_delta4 = ((Fs_delta2*(1.0-modelStruct.modelPar_nu))/modelStruct.modelPar_nu);
d_Fd_delta2_dX = d_lnoneplusEd_dX;
Fd_delta2 = lnoneplusEd;
d_Fd_delta4_dX = ((modelStruct.modelPar_nu*(Fd_delta2*(-modelStruct.d_modelPar_nu_dX)+d_Fd_delta2_dX*(1.0-modelStruct.modelPar_nu))-(Fd_delta2*(1.0-modelStruct.modelPar_nu))*modelStruct.d_modelPar_nu_dX)/modelStruct.modelPar_nu/modelStruct.modelPar_nu);
Fd_delta4 = ((Fd_delta2*(1.0-modelStruct.modelPar_nu))/modelStruct.modelPar_nu);
d_Fs_dX = (d_Fs_delta2_dX+d_Fs_delta4_dX);
Fs = (Fs_delta2+Fs_delta4);
d_Fd_dX = (d_Fd_delta2_dX+d_Fd_delta4_dX);
Fd = (Fd_delta2+Fd_delta4);
d_Vdsat2_dX = (modelStruct.modelPar_theta*d_phit_dX+modelStruct.d_modelPar_theta_dX*phit);
Vdsat2 = (modelStruct.modelPar_theta*phit);
{
double value_fabs_0 = fabs((Vdsi/Vdsat2));
double value_pow_1 = pow(value_fabs_0,modelStruct.modelPar_beta);
double  deriv_fabs_0_d0 = ((((Vdsi/Vdsat2))>=0)?(+1.0):(-1.0));
double  deriv_pow_1_d0 = ((value_fabs_0 == 0.0)?0.0:(value_pow_1*modelStruct.modelPar_beta/value_fabs_0));
double  deriv_pow_1_d1 = (value_fabs_0 == 0.0)?0.0:(log(value_fabs_0)*value_pow_1);
d_Vdsatbeta2_dX = ((deriv_pow_1_d0*(deriv_fabs_0_d0*(((Vdsat2*d_Vdsi_dX-Vdsi*d_Vdsat2_dX)/Vdsat2/Vdsat2))))+(deriv_pow_1_d1*(modelStruct.d_modelPar_beta_dX)));
Vdsatbeta2 = value_pow_1;
}
{
double value_fabs_0 = fabs((Vdsi/Vdsat2));
double value_pow_1 = pow((1.0+Vdsatbeta2),(1.0/modelStruct.modelPar_beta));
double  deriv_fabs_0_d0 = ((((Vdsi/Vdsat2))>=0)?(+1.0):(-1.0));
double  deriv_pow_1_d0 = (((1.0+Vdsatbeta2) == 0.0)?0.0:(value_pow_1*(1.0/modelStruct.modelPar_beta)/(1.0+Vdsatbeta2)));
double  deriv_pow_1_d1 = ((1.0+Vdsatbeta2) == 0.0)?0.0:(log((1.0+Vdsatbeta2))*value_pow_1);
d_f2_dX = ((value_pow_1*deriv_fabs_0_d0*(((Vdsat2*d_Vdsi_dX-Vdsi*d_Vdsat2_dX)/Vdsat2/Vdsat2))-value_fabs_0*((deriv_pow_1_d0*(d_Vdsatbeta2_dX))+(deriv_pow_1_d1*((-modelStruct.d_modelPar_beta_dX/modelStruct.modelPar_beta/modelStruct.modelPar_beta)))))/value_pow_1/value_pow_1);
f2 = (value_fabs_0/value_pow_1);
}
d_Lcrit_lin_dX = d_Leff_dX;
Lcrit_lin = Leff;
d_Lcrit_sat_dX = (modelStruct.modelPar_ksee*d_Leff_dX+modelStruct.d_modelPar_ksee_dX*Leff);
Lcrit_sat = (modelStruct.modelPar_ksee*Leff);
d_Lcrit_dX = (((1.0-f2)*d_Lcrit_lin_dX+(-d_f2_dX)*Lcrit_lin)+(f2*d_Lcrit_sat_dX+d_f2_dX*Lcrit_sat));
Lcrit = (((1.0-f2)*Lcrit_lin)+(f2*Lcrit_sat));
d_Tx_dX = (((lambda+Lcrit)*d_lambda_dX-lambda*(d_lambda_dX+d_Lcrit_dX))/(lambda+Lcrit)/(lambda+Lcrit));
Tx = (lambda/(lambda+Lcrit));
d_Qx0_dX = ((((-1.6021766208e-19)*N2D)/2.0)*((Fs*(-d_Tx_dX)+d_Fs_dX*(2.0-Tx))+(Fd*d_Tx_dX+d_Fd_dX*Tx))+((-1.6021766208e-19)*d_N2D_dX/2.0)*((Fs*(2.0-Tx))+(Fd*Tx)));
Qx0 = ((((-1.6021766208e-19)*N2D)/2.0)*((Fs*(2.0-Tx))+(Fd*Tx)));
{
double value_fabs_0 = fabs((modelStruct.modelPar_B/modelStruct.modelPar_dqm0));
double value_pow_1 = pow(value_fabs_0,3.0);
double  deriv_fabs_0_d0 = ((((modelStruct.modelPar_B/modelStruct.modelPar_dqm0))>=0)?(+1.0):(-1.0));
double  deriv_pow_1_d0 = ((value_fabs_0 == 0.0)?0.0:(value_pow_1*3.0/value_fabs_0));
d_QB_dX = (deriv_pow_1_d0*(deriv_fabs_0_d0*(((modelStruct.modelPar_dqm0*modelStruct.d_modelPar_B_dX-modelStruct.modelPar_B*modelStruct.d_modelPar_dqm0_dX)/modelStruct.modelPar_dqm0/modelStruct.modelPar_dqm0))));
QB = value_pow_1;
}
{
double value_fabs_0 = fabs(Qx0);
double value_pow_1 = pow((QB+((11.0/32.0)*value_fabs_0)),(1/3.0));
double  deriv_fabs_0_d0 = (((Qx0)>=0)?(+1.0):(-1.0));
double  deriv_pow_1_d0 = (((QB+((11.0/32.0)*value_fabs_0)) == 0.0)?0.0:(value_pow_1*(1/3.0)/(QB+((11.0/32.0)*value_fabs_0))));
d_xav_dX = ((value_pow_1*modelStruct.d_modelPar_B_dX-modelStruct.modelPar_B*(deriv_pow_1_d0*((d_QB_dX+(11.0/32.0)*deriv_fabs_0_d0*(d_Qx0_dX)))))/value_pow_1/value_pow_1);
xav = (modelStruct.modelPar_B/value_pow_1);
}
d_Cstern_dX = ((xav*modelStruct.d_modelPar_eps_dX*8.854187817e-12-(modelStruct.modelPar_eps*8.854187817e-12)*d_xav_dX)/xav/xav);
Cstern = ((modelStruct.modelPar_eps*8.854187817e-12)/xav);
d_Cgc_dX = (((modelStruct.modelPar_Cins+Cstern)*(modelStruct.modelPar_Cins*d_Cstern_dX+modelStruct.d_modelPar_Cins_dX*Cstern)-(modelStruct.modelPar_Cins*Cstern)*(modelStruct.d_modelPar_Cins_dX+d_Cstern_dX))/(modelStruct.modelPar_Cins+Cstern)/(modelStruct.modelPar_Cins+Cstern));
Cgc = ((modelStruct.modelPar_Cins*Cstern)/(modelStruct.modelPar_Cins+Cstern));
{
double value_fabs_0 = fabs((modelStruct.modelPar_nd*Vdsi));
double  deriv_fabs_0_d0 = ((((modelStruct.modelPar_nd*Vdsi))>=0)?(+1.0):(-1.0));
d_n_dX = (modelStruct.d_modelPar_n0_dX+deriv_fabs_0_d0*((modelStruct.modelPar_nd*d_Vdsi_dX+modelStruct.d_modelPar_nd_dX*Vdsi)));
n = (modelStruct.modelPar_n0+value_fabs_0);
}
// V(sf,GND) <+ ((((Vgsi+(delta*Vdsi))+(Qx0/Cgc))/n))
d_staticContributions_dX[admsBRA_ID_sf_GND] += ((n*((d_Vgsi_dX+(modelStruct.modelPar_delta*d_Vdsi_dX+modelStruct.d_modelPar_delta_dX*Vdsi))+((Cgc*d_Qx0_dX-Qx0*d_Cgc_dX)/Cgc/Cgc))-((Vgsi+(modelStruct.modelPar_delta*Vdsi))+(Qx0/Cgc))*d_n_dX)/n/n);
d_f1_dX = (((2.0*Fs)*(((2.0-Tx)*d_Fs_dX+(-d_Tx_dX)*Fs)+(Tx*d_Fd_dX+d_Tx_dX*Fd))-(((2.0-Tx)*Fs)+(Tx*Fd))*2.0*d_Fs_dX)/(2.0*Fs)/(2.0*Fs));
f1 = ((((2.0-Tx)*Fs)+(Tx*Fd))/(2.0*Fs));
d_Vdsat_dX = ((((2.0*phit)*(lambda+Leff))/(lambda+((2.0*modelStruct.modelPar_ksee)*Leff)))*d_f1_dX+(((lambda+((2.0*modelStruct.modelPar_ksee)*Leff))*((2.0*phit)*(d_lambda_dX+d_Leff_dX)+2.0*d_phit_dX*(lambda+Leff))-((2.0*phit)*(lambda+Leff))*(d_lambda_dX+((2.0*modelStruct.modelPar_ksee)*d_Leff_dX+2.0*modelStruct.d_modelPar_ksee_dX*Leff)))/(lambda+((2.0*modelStruct.modelPar_ksee)*Leff))/(lambda+((2.0*modelStruct.modelPar_ksee)*Leff)))*f1);
Vdsat = ((((2.0*phit)*(lambda+Leff))/(lambda+((2.0*modelStruct.modelPar_ksee)*Leff)))*f1);
{
double value_fabs_0 = fabs((Vdsi/Vdsat));
double value_pow_1 = pow(value_fabs_0,modelStruct.modelPar_beta);
double  deriv_fabs_0_d0 = ((((Vdsi/Vdsat))>=0)?(+1.0):(-1.0));
double  deriv_pow_1_d0 = ((value_fabs_0 == 0.0)?0.0:(value_pow_1*modelStruct.modelPar_beta/value_fabs_0));
double  deriv_pow_1_d1 = (value_fabs_0 == 0.0)?0.0:(log(value_fabs_0)*value_pow_1);
d_Vdsatbeta_dX = ((deriv_pow_1_d0*(deriv_fabs_0_d0*(((Vdsat*d_Vdsi_dX-Vdsi*d_Vdsat_dX)/Vdsat/Vdsat))))+(deriv_pow_1_d1*(modelStruct.d_modelPar_beta_dX)));
Vdsatbeta = value_pow_1;
}
{
double value_fabs_0 = fabs((Vdsi/Vdsat));
double value_pow_1 = pow((1.0+Vdsatbeta),(1.0/modelStruct.modelPar_beta));
double  deriv_fabs_0_d0 = ((((Vdsi/Vdsat))>=0)?(+1.0):(-1.0));
double  deriv_pow_1_d0 = (((1.0+Vdsatbeta) == 0.0)?0.0:(value_pow_1*(1.0/modelStruct.modelPar_beta)/(1.0+Vdsatbeta)));
double  deriv_pow_1_d1 = ((1.0+Vdsatbeta) == 0.0)?0.0:(log((1.0+Vdsatbeta))*value_pow_1);
d_Fsat_dX = ((value_pow_1*deriv_fabs_0_d0*(((Vdsat*d_Vdsi_dX-Vdsi*d_Vdsat_dX)/Vdsat/Vdsat))-value_fabs_0*((deriv_pow_1_d0*(d_Vdsatbeta_dX))+(deriv_pow_1_d1*((-modelStruct.d_modelPar_beta_dX/modelStruct.modelPar_beta/modelStruct.modelPar_beta)))))/value_pow_1/value_pow_1);
Fsat = (value_fabs_0/value_pow_1);
}
d_vx0_dX = (((lambda+((2.0*modelStruct.modelPar_ksee)*Leff))*(vT*d_lambda_dX+d_vT_dX*lambda)-(vT*lambda)*(d_lambda_dX+((2.0*modelStruct.modelPar_ksee)*d_Leff_dX+2.0*modelStruct.d_modelPar_ksee_dX*Leff)))/(lambda+((2.0*modelStruct.modelPar_ksee)*Leff))/(lambda+((2.0*modelStruct.modelPar_ksee)*Leff)));
vx0 = ((vT*lambda)/(lambda+((2.0*modelStruct.modelPar_ksee)*Leff)));
{
double value_fabs_0 = fabs(Qx0);
double  deriv_fabs_0_d0 = (((Qx0)>=0)?(+1.0):(-1.0));
d_Id_dX = (((value_fabs_0*Fsat)*vx0)*modelStruct.d_modelPar_W_dX+((value_fabs_0*Fsat)*d_vx0_dX+(value_fabs_0*d_Fsat_dX+deriv_fabs_0_d0*(d_Qx0_dX)*Fsat)*vx0)*modelStruct.modelPar_W);
Id = (((value_fabs_0*Fsat)*vx0)*modelStruct.modelPar_W);
}
// I(di,si) <+ (((type*dir)*Id))
d_staticContributions_dX[admsNodeID_di]+= (modelStruct.modelPar_type*dir)*d_Id_dX;
d_staticContributions_dX[(admsNodeID_si)]-= (modelStruct.modelPar_type*dir)*d_Id_dX;
// I(d,di) <+ (((V(d,GND)-V(di,GND))/Rd))
d_staticContributions_dX[admsNodeID_d]+= (-((probeVars[admsProbeID_V_d_GND])-(probeVars[admsProbeID_V_di_GND]))*d_Rd_dX/Rd/Rd);
d_staticContributions_dX[(admsNodeID_di)]-= (-((probeVars[admsProbeID_V_d_GND])-(probeVars[admsProbeID_V_di_GND]))*d_Rd_dX/Rd/Rd);
// I(si,s) <+ (((V(si,GND)-V(s,GND))/Rs))
d_staticContributions_dX[admsNodeID_si]+= (-((probeVars[admsProbeID_V_si_GND])-(probeVars[admsProbeID_V_s_GND]))*d_Rs_dX/Rs/Rs);
d_staticContributions_dX[(admsNodeID_s)]-= (-((probeVars[admsProbeID_V_si_GND])-(probeVars[admsProbeID_V_s_GND]))*d_Rs_dX/Rs/Rs);
}



//-----------------------------------------------------------------------------
// Function      : InstanceSensitivity::operator()
// Purpose       : return sensitivity for a single instance parameter
// Special Notes :
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
/// Compute sensitivity of a device instance's outputs to a specified instance
/// parameter
///
///
/// @param[in] entity  The device entity that owns the parameter
/// @param[in] name    The unadorned parameter name specific to the entity
/// @param[out] dfdp   The derivative of the F vector with respect to the parameter
/// @param[out] dqdp   The derivative of the Q vector with respect to the parameter
/// @param[out] dbdp   The derivative of the B vector with respect to the parameter
/// @param[out] Findices   The indices into the F vector corresponding to the elements of dfdp
/// @param[out] Qindices   The indices into the Q vector corresponding to the elements of dfdp
/// @param[out] Bindices   The indices into the B vector corresponding to the elements of dfdp
///
///
void InstanceSensitivity::operator()
(
const ParameterBase &entity,
const std::string &name,
std::vector<double> & dfdp,
std::vector<double> & dqdp,
std::vector<double> & dbdp,
std::vector<int> & Findices,
std::vector<int> & Qindices,
std::vector<int> & Bindices
) const
{
const ParameterBase * e1 = &entity;
const Instance & in = *(dynamic_cast<const Instance *> (e1));
const Model & mod =in.model_;

dfdp.resize(6+1);
dqdp.resize(6+1);
Findices.resize(6+1);
Qindices.resize(6+1);

std::vector <double> probeVars(7);
std::vector <double> d_staticContributions_dX(6+1);
std::vector <double> d_dynamicContributions_dX(6+1);


// initialize contributions to zero (automatically sets derivatives to zero)
for (int i=0; i < 6+1 ; ++i)
{
   d_staticContributions_dX[i]=0;
   d_dynamicContributions_dX[i]=0;
}

// Copy out all the model parameters (doubles) into local structure
modelSensStruct modelStruct;

//reals
modelStruct.modelPar_version=mod.version;
modelStruct.d_modelPar_version_dX=0.0;
modelStruct.modelPar_given_version=mod.given("version");
modelStruct.modelPar_W=mod.W;
modelStruct.d_modelPar_W_dX=0.0;
modelStruct.modelPar_given_W=mod.given("W");
modelStruct.modelPar_Lgdr=mod.Lgdr;
modelStruct.d_modelPar_Lgdr_dX=0.0;
modelStruct.modelPar_given_Lgdr=mod.given("Lgdr");
modelStruct.modelPar_dLg=mod.dLg;
modelStruct.d_modelPar_dLg_dX=0.0;
modelStruct.modelPar_given_dLg=mod.given("dLg");
modelStruct.modelPar_Cins=mod.Cins;
modelStruct.d_modelPar_Cins_dX=0.0;
modelStruct.modelPar_given_Cins=mod.given("Cins");
modelStruct.modelPar_Tjun=mod.Tjun;
modelStruct.d_modelPar_Tjun_dX=0.0;
modelStruct.modelPar_given_Tjun=mod.given("Tjun");
modelStruct.modelPar_energy_diff_volt=mod.energy_diff_volt;
modelStruct.d_modelPar_energy_diff_volt_dX=0.0;
modelStruct.modelPar_given_energy_diff_volt=mod.given("energy_diff_volt");
modelStruct.modelPar_delta=mod.delta;
modelStruct.d_modelPar_delta_dX=0.0;
modelStruct.modelPar_given_delta=mod.given("delta");
modelStruct.modelPar_n0=mod.n0;
modelStruct.d_modelPar_n0_dX=0.0;
modelStruct.modelPar_given_n0=mod.given("n0");
modelStruct.modelPar_Rs0=mod.Rs0;
modelStruct.d_modelPar_Rs0_dX=0.0;
modelStruct.modelPar_given_Rs0=mod.given("Rs0");
modelStruct.modelPar_mt=mod.mt;
modelStruct.d_modelPar_mt_dX=0.0;
modelStruct.modelPar_given_mt=mod.given("mt");
modelStruct.modelPar_ml=mod.ml;
modelStruct.d_modelPar_ml_dX=0.0;
modelStruct.modelPar_given_ml=mod.given("ml");
modelStruct.modelPar_nu=mod.nu;
modelStruct.d_modelPar_nu_dX=0.0;
modelStruct.modelPar_given_nu=mod.given("nu");
modelStruct.modelPar_mu_eff=mod.mu_eff;
modelStruct.d_modelPar_mu_eff_dX=0.0;
modelStruct.modelPar_given_mu_eff=mod.given("mu_eff");
modelStruct.modelPar_ksee=mod.ksee;
modelStruct.d_modelPar_ksee_dX=0.0;
modelStruct.modelPar_given_ksee=mod.given("ksee");
modelStruct.modelPar_B=mod.B;
modelStruct.d_modelPar_B_dX=0.0;
modelStruct.modelPar_given_B=mod.given("B");
modelStruct.modelPar_dqm0=mod.dqm0;
modelStruct.d_modelPar_dqm0_dX=0.0;
modelStruct.modelPar_given_dqm0=mod.given("dqm0");
modelStruct.modelPar_eps=mod.eps;
modelStruct.d_modelPar_eps_dX=0.0;
modelStruct.modelPar_given_eps=mod.given("eps");
modelStruct.modelPar_theta=mod.theta;
modelStruct.d_modelPar_theta_dX=0.0;
modelStruct.modelPar_given_theta=mod.given("theta");
modelStruct.modelPar_beta=mod.beta;
modelStruct.d_modelPar_beta_dX=0.0;
modelStruct.modelPar_given_beta=mod.given("beta");
modelStruct.modelPar_nd=mod.nd;
modelStruct.d_modelPar_nd_dX=0.0;
modelStruct.modelPar_given_nd=mod.given("nd");


// hidden reals


// non-reals (including hiddens)
modelStruct.modelPar_type=mod.type;
modelStruct.modelPar_given_type=mod.given("type");



// Copy out all the instance parameters (doubles) into local struct
// Keep a map so we can set the right one to the independent variable
// We do this solely to avoid a big ugly "if/else" block just to find the
// one parameter we're doing sensitivities on.
unordered_map <std::string,double*,HashNoCase,EqualNoCase> inParamMap;
instanceSensStruct instanceStruct;
// reals


// Copy all the real hidden instance params into local struct



// Copy all the non-real instance params into vars of their appropriate type:


// Set the one parameter whose name was passed in to be the independent
// variable for differentiation purposes.  Since we stored variable pointers, this
// makes sure that that ONE variable gets set right.
// FIXME: make this check the name first, otherwise segfault on invalid name!
*(inParamMap[name])=1.0;

//make local copies of all instance vars
//reals


//non-reals


//make local copies of all model vars
//reals


// non-reals



Linear::Vector * solVectorPtr = in.extData.nextSolVectorPtr;

// extract solution variables
probeVars[in.admsProbeID_V_sf_GND] = (*solVectorPtr)[in.li_sf];
probeVars[in.admsProbeID_V_s_GND] = (*solVectorPtr)[in.li_s];
probeVars[in.admsProbeID_V_d_GND] = (*solVectorPtr)[in.li_d];
probeVars[in.admsProbeID_V_di_GND] = (*solVectorPtr)[in.li_di];
probeVars[in.admsProbeID_V_si_GND] = (*solVectorPtr)[in.li_si];
probeVars[in.admsProbeID_V_g_GND] = (*solVectorPtr)[in.li_g];

    probeVars[in.admsProbeID_I_sf_GND] = (*solVectorPtr)[in.li_BRA_sf_GND];



// Now call  the function that does the heavy lifting.
evaluateModelEquations(
probeVars,
// probe constants
in.admsProbeID_V_sf_GND,
in.admsProbeID_V_s_GND,
in.admsProbeID_V_d_GND,
in.admsProbeID_V_di_GND,
in.admsProbeID_V_si_GND,
in.admsProbeID_V_g_GND,
in.admsProbeID_I_sf_GND,

// node constants
in.admsNodeID_d,
in.admsNodeID_g,
in.admsNodeID_s,
in.admsNodeID_di,
in.admsNodeID_si,
in.admsNodeID_sf,
in.admsBRA_ID_sf_GND,
instanceStruct,
modelStruct,
 in.admsTemperature,
 in.adms_vt_nom,
 in.getDeviceOptions().gmin,
 d_staticContributions_dX,
 d_dynamicContributions_dX,
 in);


// We now have the F and Q vector stuff, populate the dependencies:

    dfdp[in.admsNodeID_d] += d_staticContributions_dX[in.admsNodeID_d];
    dqdp[in.admsNodeID_d] += d_dynamicContributions_dX[in.admsNodeID_d];
    Findices[in.admsNodeID_d] = in.li_d;
    Qindices[in.admsNodeID_d] = in.li_d;
    dfdp[in.admsNodeID_g] += d_staticContributions_dX[in.admsNodeID_g];
    dqdp[in.admsNodeID_g] += d_dynamicContributions_dX[in.admsNodeID_g];
    Findices[in.admsNodeID_g] = in.li_g;
    Qindices[in.admsNodeID_g] = in.li_g;
    dfdp[in.admsNodeID_s] += d_staticContributions_dX[in.admsNodeID_s];
    dqdp[in.admsNodeID_s] += d_dynamicContributions_dX[in.admsNodeID_s];
    Findices[in.admsNodeID_s] = in.li_s;
    Qindices[in.admsNodeID_s] = in.li_s;
    dfdp[in.admsNodeID_di] += d_staticContributions_dX[in.admsNodeID_di];
    dqdp[in.admsNodeID_di] += d_dynamicContributions_dX[in.admsNodeID_di];
    Findices[in.admsNodeID_di] = in.li_di;
    Qindices[in.admsNodeID_di] = in.li_di;
    dfdp[in.admsNodeID_si] += d_staticContributions_dX[in.admsNodeID_si];
    dqdp[in.admsNodeID_si] += d_dynamicContributions_dX[in.admsNodeID_si];
    Findices[in.admsNodeID_si] = in.li_si;
    Qindices[in.admsNodeID_si] = in.li_si;
    dfdp[in.admsNodeID_sf] += d_staticContributions_dX[in.admsNodeID_sf];
    dqdp[in.admsNodeID_sf] += d_dynamicContributions_dX[in.admsNodeID_sf];
    Findices[in.admsNodeID_sf] = in.li_sf;
    Qindices[in.admsNodeID_sf] = in.li_sf;
  dfdp[in.admsBRA_ID_sf_GND] += d_staticContributions_dX[in.admsBRA_ID_sf_GND];
  dqdp[in.admsBRA_ID_sf_GND] += d_dynamicContributions_dX[in.admsBRA_ID_sf_GND];
  Findices[in.admsBRA_ID_sf_GND] = in.li_BRA_sf_GND;
  Qindices[in.admsBRA_ID_sf_GND] = in.li_BRA_sf_GND;


}

//-----------------------------------------------------------------------------
// Function      : ModelSensitivity::operator()
// Purpose       : return sensitivity for a single model parameter
// Special Notes :
// Scope         : public
// Creator       : admsXml
// Creation Date :
//-----------------------------------------------------------------------------
/// Compute sensitivity to a specified model
/// parameter of all device instances of that model's outputs
///
///
/// @param[in] entity  The device entity that owns the parameter
/// @param[in] name    The unadorned parameter name specific to the entity
/// @param[out] dfdp   The derivative of the F vector with respect to the parameter
/// @param[out] dqdp   The derivative of the Q vector with respect to the parameter
/// @param[out] dbdp   The derivative of the B vector with respect to the parameter
/// @param[out] Findices   The indices into the F vector corresponding to the elements of dfdp
/// @param[out] Qindices   The indices into the Q vector corresponding to the elements of dfdp
/// @param[out] Bindices   The indices into the B vector corresponding to the elements of dfdp
///
///
void ModelSensitivity::operator()
(
const ParameterBase &entity,
const std::string &name,
std::vector<double> & dfdp,
std::vector<double> & dqdp,
std::vector<double> & dbdp,
std::vector<int> & Findices,
std::vector<int> & Qindices,
std::vector<int> & Bindices
) const
{
const ParameterBase * e1 = &entity;
const Model & mod = *(dynamic_cast<const Model *> (e1));
int sizeInstance = mod.instanceContainer.size();

dfdp.resize((6+1)*sizeInstance);
dqdp.resize((6+1)*sizeInstance);
Findices.resize((6+1)*sizeInstance);
Qindices.resize((6+1)*sizeInstance);

std::vector <double> probeVars(7);
std::vector <double> d_staticContributions_dX(6+1);
std::vector <double> d_dynamicContributions_dX(6+1);


// Copy out all the model parameters (doubles) into local structure
modelSensStruct modelStruct;

// Keep a map so we can set the right one to the independent variable
// We do this solely to avoid a big ugly "if/else" block just to find the
// one parameter we're doing sensitivities on.
unordered_map <std::string,double*,HashNoCase,EqualNoCase> modParamMap;

// reals
modelStruct.modelPar_version=mod.version;
modelStruct.d_modelPar_version_dX=0.0;
modelStruct.modelPar_given_version=mod.given("version");
modParamMap["version"] = &(modelStruct.d_modelPar_version_dX);
modelStruct.modelPar_W=mod.W;
modelStruct.d_modelPar_W_dX=0.0;
modelStruct.modelPar_given_W=mod.given("W");
modParamMap["W"] = &(modelStruct.d_modelPar_W_dX);
modelStruct.modelPar_Lgdr=mod.Lgdr;
modelStruct.d_modelPar_Lgdr_dX=0.0;
modelStruct.modelPar_given_Lgdr=mod.given("Lgdr");
modParamMap["Lgdr"] = &(modelStruct.d_modelPar_Lgdr_dX);
modelStruct.modelPar_dLg=mod.dLg;
modelStruct.d_modelPar_dLg_dX=0.0;
modelStruct.modelPar_given_dLg=mod.given("dLg");
modParamMap["dLg"] = &(modelStruct.d_modelPar_dLg_dX);
modelStruct.modelPar_Cins=mod.Cins;
modelStruct.d_modelPar_Cins_dX=0.0;
modelStruct.modelPar_given_Cins=mod.given("Cins");
modParamMap["Cins"] = &(modelStruct.d_modelPar_Cins_dX);
modelStruct.modelPar_Tjun=mod.Tjun;
modelStruct.d_modelPar_Tjun_dX=0.0;
modelStruct.modelPar_given_Tjun=mod.given("Tjun");
modParamMap["Tjun"] = &(modelStruct.d_modelPar_Tjun_dX);
modelStruct.modelPar_energy_diff_volt=mod.energy_diff_volt;
modelStruct.d_modelPar_energy_diff_volt_dX=0.0;
modelStruct.modelPar_given_energy_diff_volt=mod.given("energy_diff_volt");
modParamMap["energy_diff_volt"] = &(modelStruct.d_modelPar_energy_diff_volt_dX);
modelStruct.modelPar_delta=mod.delta;
modelStruct.d_modelPar_delta_dX=0.0;
modelStruct.modelPar_given_delta=mod.given("delta");
modParamMap["delta"] = &(modelStruct.d_modelPar_delta_dX);
modelStruct.modelPar_n0=mod.n0;
modelStruct.d_modelPar_n0_dX=0.0;
modelStruct.modelPar_given_n0=mod.given("n0");
modParamMap["n0"] = &(modelStruct.d_modelPar_n0_dX);
modelStruct.modelPar_Rs0=mod.Rs0;
modelStruct.d_modelPar_Rs0_dX=0.0;
modelStruct.modelPar_given_Rs0=mod.given("Rs0");
modParamMap["Rs0"] = &(modelStruct.d_modelPar_Rs0_dX);
modelStruct.modelPar_mt=mod.mt;
modelStruct.d_modelPar_mt_dX=0.0;
modelStruct.modelPar_given_mt=mod.given("mt");
modParamMap["mt"] = &(modelStruct.d_modelPar_mt_dX);
modelStruct.modelPar_ml=mod.ml;
modelStruct.d_modelPar_ml_dX=0.0;
modelStruct.modelPar_given_ml=mod.given("ml");
modParamMap["ml"] = &(modelStruct.d_modelPar_ml_dX);
modelStruct.modelPar_nu=mod.nu;
modelStruct.d_modelPar_nu_dX=0.0;
modelStruct.modelPar_given_nu=mod.given("nu");
modParamMap["nu"] = &(modelStruct.d_modelPar_nu_dX);
modelStruct.modelPar_mu_eff=mod.mu_eff;
modelStruct.d_modelPar_mu_eff_dX=0.0;
modelStruct.modelPar_given_mu_eff=mod.given("mu_eff");
modParamMap["mu_eff"] = &(modelStruct.d_modelPar_mu_eff_dX);
modelStruct.modelPar_ksee=mod.ksee;
modelStruct.d_modelPar_ksee_dX=0.0;
modelStruct.modelPar_given_ksee=mod.given("ksee");
modParamMap["ksee"] = &(modelStruct.d_modelPar_ksee_dX);
modelStruct.modelPar_B=mod.B;
modelStruct.d_modelPar_B_dX=0.0;
modelStruct.modelPar_given_B=mod.given("B");
modParamMap["B"] = &(modelStruct.d_modelPar_B_dX);
modelStruct.modelPar_dqm0=mod.dqm0;
modelStruct.d_modelPar_dqm0_dX=0.0;
modelStruct.modelPar_given_dqm0=mod.given("dqm0");
modParamMap["dqm0"] = &(modelStruct.d_modelPar_dqm0_dX);
modelStruct.modelPar_eps=mod.eps;
modelStruct.d_modelPar_eps_dX=0.0;
modelStruct.modelPar_given_eps=mod.given("eps");
modParamMap["eps"] = &(modelStruct.d_modelPar_eps_dX);
modelStruct.modelPar_theta=mod.theta;
modelStruct.d_modelPar_theta_dX=0.0;
modelStruct.modelPar_given_theta=mod.given("theta");
modParamMap["theta"] = &(modelStruct.d_modelPar_theta_dX);
modelStruct.modelPar_beta=mod.beta;
modelStruct.d_modelPar_beta_dX=0.0;
modelStruct.modelPar_given_beta=mod.given("beta");
modParamMap["beta"] = &(modelStruct.d_modelPar_beta_dX);
modelStruct.modelPar_nd=mod.nd;
modelStruct.d_modelPar_nd_dX=0.0;
modelStruct.modelPar_given_nd=mod.given("nd");
modParamMap["nd"] = &(modelStruct.d_modelPar_nd_dX);


// hidden reals


// non-reals (including hiddens)
modelStruct.modelPar_type=mod.type;
modelStruct.modelPar_given_type=mod.given("type");


// Set the one parameter whose name was passed in to be the independent
// variable for differentiation purposes.  Since we stored variable pointers, this
// makes sure that that ONE variable gets set right.
// FIXME: make this check name for presence first!  Segfault on invalid.
*(modParamMap[name])=1.0;

//make local copies of all model vars
//reals


// non-reals



// Now loop over all instances and do the deed
int inst=0;
for (std::vector<Instance*>::const_iterator in_it=mod.instanceContainer.begin(); in_it != mod.instanceContainer.end(); ++in_it,++inst)
{

  Instance & in=*(*in_it);
  // initialize contributions to zero (automatically sets derivatives to zero)
  for (int i=0; i < 6+1 ; ++i)
  {
  d_staticContributions_dX[i]=0;
  d_dynamicContributions_dX[i]=0;
  }



  // Copy out all the instance parameters (doubles) into local struct
 instanceSensStruct instanceStruct;

 // reals


  // real hidden instance


  // Copy all the non-real instance params into vars of their appropriate type:




  // If there are any instance parameters that were not given, and have
  // corresponding model params, copy the model param into the instance.
  // This was already done by the instance constructor, but we do it again
  // because now we're propagating derivatives, and the user could be trying
  // to get sensitivity to the model parameter.


  //make local copies of all instance vars
  //reals


  //non-reals



  Linear::Vector * solVectorPtr = in.extData.nextSolVectorPtr;

  // extract solution variables
probeVars[in.admsProbeID_V_sf_GND] = (*solVectorPtr)[in.li_sf];
probeVars[in.admsProbeID_V_s_GND] = (*solVectorPtr)[in.li_s];
probeVars[in.admsProbeID_V_d_GND] = (*solVectorPtr)[in.li_d];
probeVars[in.admsProbeID_V_di_GND] = (*solVectorPtr)[in.li_di];
probeVars[in.admsProbeID_V_si_GND] = (*solVectorPtr)[in.li_si];
probeVars[in.admsProbeID_V_g_GND] = (*solVectorPtr)[in.li_g];
probeVars[in.admsProbeID_I_sf_GND] = (*solVectorPtr)[in.li_BRA_sf_GND];




// Now call  the function that does the heavy lifting.

evaluateModelEquations(
probeVars,
// probe constants
in.admsProbeID_V_sf_GND,
in.admsProbeID_V_s_GND,
in.admsProbeID_V_d_GND,
in.admsProbeID_V_di_GND,
in.admsProbeID_V_si_GND,
in.admsProbeID_V_g_GND,
in.admsProbeID_I_sf_GND,

// node constants
in.admsNodeID_d,
in.admsNodeID_g,
in.admsNodeID_s,
in.admsNodeID_di,
in.admsNodeID_si,
in.admsNodeID_sf,
in.admsBRA_ID_sf_GND,
instanceStruct,
modelStruct,
 in.admsTemperature,
 in.adms_vt_nom,
 in.getDeviceOptions().gmin,
 d_staticContributions_dX,
 d_dynamicContributions_dX,
 in);


  // We now have the F and Q vector stuff, populate the dependencies:

    dfdp[in.admsNodeID_d+inst*(6+1)] += d_staticContributions_dX[in.admsNodeID_d];
    dqdp[in.admsNodeID_d+inst*(6+1)] += d_dynamicContributions_dX[in.admsNodeID_d];
    Findices[in.admsNodeID_d+inst*(6+1)] = in.li_d;
    Qindices[in.admsNodeID_d+inst*(6+1)] = in.li_d;
    dfdp[in.admsNodeID_g+inst*(6+1)] += d_staticContributions_dX[in.admsNodeID_g];
    dqdp[in.admsNodeID_g+inst*(6+1)] += d_dynamicContributions_dX[in.admsNodeID_g];
    Findices[in.admsNodeID_g+inst*(6+1)] = in.li_g;
    Qindices[in.admsNodeID_g+inst*(6+1)] = in.li_g;
    dfdp[in.admsNodeID_s+inst*(6+1)] += d_staticContributions_dX[in.admsNodeID_s];
    dqdp[in.admsNodeID_s+inst*(6+1)] += d_dynamicContributions_dX[in.admsNodeID_s];
    Findices[in.admsNodeID_s+inst*(6+1)] = in.li_s;
    Qindices[in.admsNodeID_s+inst*(6+1)] = in.li_s;
    dfdp[in.admsNodeID_di+inst*(6+1)] += d_staticContributions_dX[in.admsNodeID_di];
    dqdp[in.admsNodeID_di+inst*(6+1)] += d_dynamicContributions_dX[in.admsNodeID_di];
    Findices[in.admsNodeID_di+inst*(6+1)] = in.li_di;
    Qindices[in.admsNodeID_di+inst*(6+1)] = in.li_di;
    dfdp[in.admsNodeID_si+inst*(6+1)] += d_staticContributions_dX[in.admsNodeID_si];
    dqdp[in.admsNodeID_si+inst*(6+1)] += d_dynamicContributions_dX[in.admsNodeID_si];
    Findices[in.admsNodeID_si+inst*(6+1)] = in.li_si;
    Qindices[in.admsNodeID_si+inst*(6+1)] = in.li_si;
    dfdp[in.admsNodeID_sf+inst*(6+1)] += d_staticContributions_dX[in.admsNodeID_sf];
    dqdp[in.admsNodeID_sf+inst*(6+1)] += d_dynamicContributions_dX[in.admsNodeID_sf];
    Findices[in.admsNodeID_sf+inst*(6+1)] = in.li_sf;
    Qindices[in.admsNodeID_sf+inst*(6+1)] = in.li_sf;
    dfdp[in.admsBRA_ID_sf_GND+inst*(6+1)] += d_staticContributions_dX[in.admsBRA_ID_sf_GND];
    dqdp[in.admsBRA_ID_sf_GND+inst*(6+1)] += d_dynamicContributions_dX[in.admsBRA_ID_sf_GND];
    Findices[in.admsBRA_ID_sf_GND+inst*(6+1)] = in.li_BRA_sf_GND;
    Qindices[in.admsBRA_ID_sf_GND+inst*(6+1)] = in.li_BRA_sf_GND;
}

}

#endif // Xyce_ADMS_SENSITIVITIES

} // namespace ADMSmvs_2_0_0_etsoi
} // namespace Device
} // namespace Xyce
